diff --git a/docs/plans/2026-06-06-preview-bridge.md b/docs/plans/2026-06-06-preview-bridge.md new file mode 100644 index 0000000..f0d12c2 --- /dev/null +++ b/docs/plans/2026-06-06-preview-bridge.md @@ -0,0 +1,1494 @@ +# Preview Bridge Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** A proxy-based live preview tab that the IDE opens via Cmd+click on terminal URLs, stays in sync with file saves, and lets you select elements to paste their CSS selector + screenshot path into the active terminal. + +**Architecture:** A new `sidecar-client` pnpm package builds a self-contained `client.js` (VanJS + html2canvas) that gets embedded into the Go binary. The Go server adds three endpoints: a cookie-based reverse proxy that injects `client.js` into HTML responses, a static handler for `client.js`, and a WebSocket hub that relays messages between the IDE tab and the proxy tab. The frontend terminal gains a URL link provider so normal-click opens direct and Cmd+click opens via proxy. + +**Tech Stack:** Go (`net/http/httputil`, `github.com/coder/websocket`), TypeScript, VanJS 1.x, html2canvas, Vite lib mode, xterm.js `ILinkProvider` + +--- + +## File Map + +**New files — sidecar-client package** +- `sidecar-client/package.json` — package manifest, `@browser-sidecar/sidecar-client` +- `sidecar-client/vite.config.ts` — lib mode, iife, single entry +- `sidecar-client/tsconfig.json` — strict TypeScript +- `sidecar-client/src/selector.ts` — CSS selector capture (pure, testable) +- `sidecar-client/src/selector.test.ts` — vitest unit tests +- `sidecar-client/src/pill.ts` — VanJS pill in Shadow DOM +- `sidecar-client/src/screenshot.ts` — html2canvas element screenshot +- `sidecar-client/src/index.ts` — WS client + selection logic entry + +**New files — Go sidecar package** +- `server-go/internal/sidecar/hub.go` — WS hub, screenshot interception +- `server-go/internal/sidecar/hub_test.go` — hub unit tests +- `server-go/internal/sidecar/proxy.go` — cookie-based reverse proxy + HTML injection +- `server-go/internal/sidecar/proxy_test.go` — proxy injection tests +- `server-go/internal/sidecar/embed.go` — `//go:embed` for client.js +- `server-go/internal/sidecar/routes.go` — `RegisterRoutes(r, hub)` +- `server-go/internal/sidecar/static/client.js` — placeholder (overwritten by build) + +**New files — frontend** +- `frontend/src/modules/terminal/lib/terminal-url-links.ts` — URL link provider (pure) +- `frontend/src/modules/terminal/lib/terminal-url-links.test.ts` — vitest tests +- `frontend/src/modules/terminal/lib/sidecar-ws.ts` — singleton WS composable + +**Modified files** +- `pnpm-workspace.yaml` — add `sidecar-client` +- `package.json` — prepend sidecar-client build to `build` script +- `scripts/build-go.mjs` — copy `sidecar-client/dist/client.js` → `server-go/internal/sidecar/static/client.js` +- `server-go/internal/api/router.go` — create hub, register sidecar routes, pass hub to workspace routes +- `server-go/internal/workspace/router.go` — accept hub, call `hub.BroadcastRefresh()` after file write +- `frontend/src/modules/terminal/pages/Terminal.vue` — register URL link provider, init sidecar WS, handle element-selected + +--- + +## Task 1: sidecar-client package scaffold + +**Files:** +- Create: `sidecar-client/package.json` +- Create: `sidecar-client/vite.config.ts` +- Create: `sidecar-client/tsconfig.json` +- Modify: `pnpm-workspace.yaml` + +- [ ] **Step 1: Add sidecar-client to workspace** + +Edit `pnpm-workspace.yaml`: +```yaml +packages: + - frontend + - cli + - landing + - sidecar-client +allowBuilds: + esbuild: true + sharp: true + vue-demi: true +``` + +- [ ] **Step 2: Create package.json** + +```json +{ + "name": "@browser-sidecar/sidecar-client", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "build": "vite build", + "test": "vitest run" + }, + "dependencies": { + "html2canvas": "^1.4.1", + "vanjs-core": "^1.6.0" + }, + "devDependencies": { + "typescript": "^5.8.3", + "vite": "^6.3.5", + "vitest": "^3.1.3" + } +} +``` + +- [ ] **Step 3: Create vite.config.ts** + +```typescript +import { defineConfig } from "vite"; + +export default defineConfig({ + build: { + lib: { + entry: "src/index.ts", + name: "SidecarClient", + formats: ["iife"], + fileName: () => "client.js", + }, + outDir: "dist", + minify: true, + rollupOptions: { + output: { + inlineDynamicImports: true, + }, + }, + }, +}); +``` + +- [ ] **Step 4: Create tsconfig.json** + +```json +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "lib": ["ES2020", "DOM"], + "outDir": "dist" + }, + "include": ["src"] +} +``` + +- [ ] **Step 5: Install dependencies** + +```bash +pnpm install +``` + +Expected: packages installed, `sidecar-client` appears in workspace. + +- [ ] **Step 6: Commit** + +```bash +git add pnpm-workspace.yaml sidecar-client/ +git commit -m "chore: scaffold sidecar-client package" +``` + +--- + +## Task 2: CSS selector capture + +**Files:** +- Create: `sidecar-client/src/selector.ts` +- Create: `sidecar-client/src/selector.test.ts` + +- [ ] **Step 1: Write the failing test** + +Create `sidecar-client/src/selector.test.ts`: +```typescript +import { describe, it, expect, beforeEach } from "vitest"; +import { buildSelector } from "./selector"; + +function el(tag: string, attrs: Record = {}): Element { + const e = document.createElement(tag); + if (attrs.id) e.id = attrs.id; + if (attrs.class) e.className = attrs.class; + return e; +} + +describe("buildSelector", () => { + it("returns tag name for element with no id or classes", () => { + expect(buildSelector(el("div"))).toBe("div"); + }); + + it("stops at id and uses #id", () => { + const e = el("div", { id: "main" }); + expect(buildSelector(e)).toBe("#main"); + }); + + it("includes stable class names", () => { + const e = el("button", { class: "btn primary" }); + expect(buildSelector(e)).toBe("button.btn.primary"); + }); + + it("skips dynamic CSS-module-like class names", () => { + // matches /^[a-z]+-[a-z0-9]{4,}$/i + const e = el("div", { class: "card-header abc-1234 stable" }); + expect(buildSelector(e)).toBe("div.card-header.stable"); + }); + + it("limits to first two stable classes", () => { + const e = el("div", { class: "a b c d" }); + expect(buildSelector(e)).toBe("div.a.b"); + }); + + it("walks ancestor chain up to body", () => { + const parent = el("section", { class: "container" }); + const child = el("p"); + parent.appendChild(child); + document.body.appendChild(parent); + expect(buildSelector(child)).toBe("section.container > p"); + document.body.removeChild(parent); + }); +}); +``` + +- [ ] **Step 2: Run test to verify it fails** + +```bash +cd sidecar-client && pnpm test +``` +Expected: FAIL — `buildSelector` not found. + +- [ ] **Step 3: Implement selector.ts** + +Create `sidecar-client/src/selector.ts`: +```typescript +const DYNAMIC_CLASS_RE = /^[a-z]+-[a-z0-9]{4,}$/i; + +export function buildSelector(el: Element): string { + const parts: string[] = []; + let current: Element | null = el; + + while (current && current !== document.body) { + if (current.id) { + parts.unshift(`#${current.id}`); + break; + } + + const tag = current.tagName.toLowerCase(); + const stableClasses = Array.from(current.classList) + .filter((c) => !DYNAMIC_CLASS_RE.test(c)) + .slice(0, 2); + + const segment = + stableClasses.length > 0 ? `${tag}.${stableClasses.join(".")}` : tag; + parts.unshift(segment); + current = current.parentElement; + } + + return parts.join(" > ") || el.tagName.toLowerCase(); +} +``` + +- [ ] **Step 4: Run test to verify it passes** + +```bash +cd sidecar-client && pnpm test +``` +Expected: all 6 tests PASS. + +- [ ] **Step 5: Commit** + +```bash +git add sidecar-client/src/selector.ts sidecar-client/src/selector.test.ts +git commit -m "feat(sidecar-client): add CSS selector capture" +``` + +--- + +## Task 3: Selection pill (VanJS + Shadow DOM) + +**Files:** +- Create: `sidecar-client/src/pill.ts` + +- [ ] **Step 1: Create pill.ts** + +```typescript +import van from "vanjs-core"; + +const PILL_STYLES = ` + :host { all: initial; } + .pill { + display: flex; align-items: center; gap: 8px; + background: #1e1e2e; border-radius: 6px; + padding: 6px 12px; cursor: pointer; + font-family: monospace; font-size: 12px; + box-shadow: 0 2px 8px rgba(0,0,0,0.4); + user-select: none; + } + .dot { + width: 8px; height: 8px; border-radius: 50%; + transition: background 0.15s; + } + .dot.off { background: #6c7086; } + .dot.on { background: #a6e3a1; } + .label { color: #cdd6f4; } +`; + +export interface Pill { + setActive(v: boolean): void; +} + +export function mountPill(onToggle: (active: boolean) => void): Pill { + const { div, span, style } = van.tags; + const active = van.state(false); + + const host = document.createElement("div"); + host.setAttribute("data-sidecar-pill", ""); + host.style.cssText = + "position:fixed;bottom:16px;left:16px;z-index:2147483647;pointer-events:auto"; + document.body.appendChild(host); + + const shadow = host.attachShadow({ mode: "open" }); + + const pill = div( + { + class: "pill", + onclick: () => { + active.val = !active.val; + onToggle(active.val); + }, + }, + span({ class: () => `dot ${active.val ? "on" : "off"}` }), + span({ class: "label" }, "Select"), + ); + + van.add(shadow, style(PILL_STYLES), pill); + + return { + setActive(v: boolean) { + active.val = v; + }, + }; +} +``` + +- [ ] **Step 2: Commit** + +```bash +git add sidecar-client/src/pill.ts +git commit -m "feat(sidecar-client): add VanJS selection pill with shadow DOM" +``` + +--- + +## Task 4: Screenshot capture + +**Files:** +- Create: `sidecar-client/src/screenshot.ts` + +- [ ] **Step 1: Create screenshot.ts** + +```typescript +import html2canvas from "html2canvas"; + +export async function captureScreenshot(el: HTMLElement): Promise { + const rect = el.getBoundingClientRect(); + const canvas = await html2canvas(document.body, { + x: rect.left + window.scrollX, + y: rect.top + window.scrollY, + width: rect.width, + height: rect.height, + useCORS: true, + logging: false, + }); + // Remove the "data:image/png;base64," prefix — Go decodes raw base64 + return canvas.toDataURL("image/png").split(",")[1] ?? ""; +} +``` + +- [ ] **Step 2: Commit** + +```bash +git add sidecar-client/src/screenshot.ts +git commit -m "feat(sidecar-client): add element screenshot capture" +``` + +--- + +## Task 5: client.js entry point + +**Files:** +- Create: `sidecar-client/src/index.ts` + +- [ ] **Step 1: Create index.ts** + +```typescript +import { mountPill } from "./pill"; +import { buildSelector } from "./selector"; +import { captureScreenshot } from "./screenshot"; + +const WS_URL = (() => { + const proto = location.protocol === "https:" ? "wss:" : "ws:"; + return `${proto}//${location.host}/sidecar/ws`; +})(); + +let ws: WebSocket | null = null; +let selectionActive = false; + +function connect() { + ws = new WebSocket(WS_URL); + ws.addEventListener("message", (e) => { + try { + const msg = JSON.parse(e.data as string) as { type: string }; + if (msg.type === "refresh") location.reload(); + } catch { + // ignore malformed messages + } + }); + ws.addEventListener("close", () => setTimeout(connect, 2000)); +} + +function onMouseOver(e: MouseEvent) { + const target = e.target as HTMLElement; + if (target.closest("[data-sidecar-pill]")) return; + target.style.outline = "2px solid #89b4fa"; +} + +function onMouseOut(e: MouseEvent) { + (e.target as HTMLElement).style.outline = ""; +} + +async function onClick(e: MouseEvent) { + const target = e.target as HTMLElement; + if (target.closest("[data-sidecar-pill]")) return; + e.preventDefault(); + e.stopPropagation(); + + const selector = buildSelector(target); + const screenshot = await captureScreenshot(target); + + ws?.send(JSON.stringify({ type: "element-selected", selector, screenshot })); + + selectionActive = false; + pill.setActive(false); + document.removeEventListener("mouseover", onMouseOver); + document.removeEventListener("mouseout", onMouseOut); + document.removeEventListener("click", onClick, true); +} + +const pill = mountPill((active) => { + selectionActive = active; + if (active) { + document.addEventListener("mouseover", onMouseOver); + document.addEventListener("mouseout", onMouseOut); + document.addEventListener("click", onClick, true); + } else { + document.removeEventListener("mouseover", onMouseOver); + document.removeEventListener("mouseout", onMouseOut); + document.removeEventListener("click", onClick, true); + } +}); + +connect(); +``` + +- [ ] **Step 2: Build and verify** + +```bash +cd sidecar-client && pnpm build +``` +Expected: `sidecar-client/dist/client.js` created, no TypeScript errors. + +- [ ] **Step 3: Commit** + +```bash +git add sidecar-client/src/index.ts sidecar-client/dist/ +git commit -m "feat(sidecar-client): add WS client entry with selection mode" +``` + +--- + +## Task 6: Go WebSocket hub + +**Files:** +- Create: `server-go/internal/sidecar/hub.go` +- Create: `server-go/internal/sidecar/hub_test.go` + +- [ ] **Step 1: Write the failing test** + +Create `server-go/internal/sidecar/hub_test.go`: +```go +package sidecar + +import ( + "encoding/json" + "os" + "path/filepath" + "testing" +) + +func TestProcessIncoming_passesThrough(t *testing.T) { + h := NewHub(t.TempDir()) + raw := []byte(`{"type":"refresh"}`) + got := h.processIncoming(raw) + if string(got) != string(raw) { + t.Fatalf("expected passthrough, got %s", got) + } +} + +func TestProcessIncoming_savesScreenshot(t *testing.T) { + dir := t.TempDir() + h := NewHub(dir) + + // 1x1 red PNG base64 + pngB64 := "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI6QAAAABJRU5ErkJggg==" + msg := map[string]string{ + "type": "element-selected", + "selector": ".foo > p", + "screenshot": pngB64, + } + raw, _ := json.Marshal(msg) + + out := h.processIncoming(raw) + + var result map[string]string + if err := json.Unmarshal(out, &result); err != nil { + t.Fatalf("invalid JSON: %v", err) + } + if _, ok := result["screenshot"]; ok { + t.Error("screenshot field should be removed") + } + path, ok := result["screenshotPath"] + if !ok { + t.Fatal("screenshotPath missing") + } + if _, err := os.Stat(path); err != nil { + t.Fatalf("screenshot file not found at %s: %v", path, err) + } + if filepath.Ext(path) != ".png" { + t.Errorf("expected .png extension, got %s", filepath.Ext(path)) + } + if result["selector"] != ".foo > p" { + t.Errorf("selector modified unexpectedly: %s", result["selector"]) + } +} + +func TestProcessIncoming_invalidBase64(t *testing.T) { + h := NewHub(t.TempDir()) + raw := []byte(`{"type":"element-selected","selector":".a","screenshot":"!!!notbase64!!!"}`) + out := h.processIncoming(raw) + // should return original message unchanged + if string(out) != string(raw) { + t.Fatalf("expected original on bad base64, got %s", out) + } +} +``` + +- [ ] **Step 2: Run test to verify it fails** + +```bash +cd server-go && go test ./internal/sidecar/... +``` +Expected: compile error — package does not exist. + +- [ ] **Step 3: Implement hub.go** + +Create `server-go/internal/sidecar/hub.go`: +```go +package sidecar + +import ( + "context" + "encoding/base64" + "encoding/json" + "fmt" + "log/slog" + "net/http" + "os" + "path/filepath" + "sync" + + "github.com/coder/websocket" + "github.com/google/uuid" +) + +type hubClient struct { + send chan []byte + done chan struct{} +} + +// Hub relays messages between the IDE tab and the proxy tab. +// It intercepts element-selected messages to persist screenshots to disk. +type Hub struct { + mu sync.RWMutex + clients map[*hubClient]struct{} + dataDir string // directory where screenshot files are saved +} + +func NewHub(dataDir string) *Hub { + return &Hub{ + clients: make(map[*hubClient]struct{}), + dataDir: dataDir, + } +} + +func (h *Hub) add(c *hubClient) { + h.mu.Lock() + h.clients[c] = struct{}{} + h.mu.Unlock() +} + +func (h *Hub) remove(c *hubClient) { + h.mu.Lock() + delete(h.clients, c) + h.mu.Unlock() + close(c.done) +} + +func (h *Hub) broadcast(msg []byte, exclude *hubClient) { + h.mu.RLock() + defer h.mu.RUnlock() + for c := range h.clients { + if c == exclude { + continue + } + select { + case c.send <- msg: + default: + } + } +} + +// BroadcastRefresh sends {"type":"refresh"} to all connected clients. +func (h *Hub) BroadcastRefresh() { + h.broadcast([]byte(`{"type":"refresh"}`), nil) +} + +// processIncoming intercepts element-selected messages: saves the base64 screenshot +// to dataDir/files/.png and replaces the screenshot field with screenshotPath. +// All other message types are returned unchanged. +func (h *Hub) processIncoming(raw []byte) []byte { + var m map[string]json.RawMessage + if err := json.Unmarshal(raw, &m); err != nil { + return raw + } + var msgType string + if err := json.Unmarshal(m["type"], &msgType); err != nil { + return raw + } + if msgType != "element-selected" { + return raw + } + + screenshotRaw, ok := m["screenshot"] + if !ok { + return raw + } + var b64 string + if err := json.Unmarshal(screenshotRaw, &b64); err != nil || b64 == "" { + return raw + } + + data, err := base64.StdEncoding.DecodeString(b64) + if err != nil { + slog.Warn("sidecar: invalid screenshot base64", "err", err) + return raw + } + + dir := filepath.Join(h.dataDir, "files") + if err := os.MkdirAll(dir, 0755); err != nil { + slog.Warn("sidecar: cannot create files dir", "err", err) + return raw + } + + fname := fmt.Sprintf("%s.png", uuid.New().String()) + fpath := filepath.Join(dir, fname) + if err := os.WriteFile(fpath, data, 0644); err != nil { + slog.Warn("sidecar: cannot write screenshot", "err", err) + return raw + } + + delete(m, "screenshot") + fpathJSON, _ := json.Marshal(fpath) + m["screenshotPath"] = fpathJSON + + enriched, err := json.Marshal(m) + if err != nil { + return raw + } + return enriched +} + +// ServeWS upgrades the request to a WebSocket connection and joins the hub. +func (h *Hub) ServeWS(w http.ResponseWriter, r *http.Request) { + conn, err := websocket.Accept(w, r, &websocket.AcceptOptions{ + InsecureSkipVerify: true, + }) + if err != nil { + slog.Error("sidecar ws accept", "err", err) + return + } + + c := &hubClient{ + send: make(chan []byte, 64), + done: make(chan struct{}), + } + h.add(c) + + ctx, cancel := context.WithCancel(r.Context()) + defer cancel() + + go func() { + defer conn.Close(websocket.StatusNormalClosure, "") + for { + select { + case msg := <-c.send: + if err := conn.Write(ctx, websocket.MessageText, msg); err != nil { + return + } + case <-c.done: + return + case <-ctx.Done(): + return + } + } + }() + + for { + _, msg, err := conn.Read(ctx) + if err != nil { + break + } + outgoing := h.processIncoming(msg) + h.broadcast(outgoing, c) + } + + h.remove(c) +} +``` + +- [ ] **Step 4: Run tests** + +```bash +cd server-go && go test ./internal/sidecar/... +``` +Expected: 3 tests PASS. + +- [ ] **Step 5: Commit** + +```bash +git add server-go/internal/sidecar/hub.go server-go/internal/sidecar/hub_test.go +git commit -m "feat(go): add sidecar WebSocket hub with screenshot persistence" +``` + +--- + +## Task 7: Go reverse proxy with HTML injection + +**Files:** +- Create: `server-go/internal/sidecar/proxy.go` +- Create: `server-go/internal/sidecar/proxy_test.go` + +- [ ] **Step 1: Write the failing test** + +Create `server-go/internal/sidecar/proxy_test.go`: +```go +package sidecar + +import ( + "io" + "net/http" + "net/http/httptest" + "strings" + "testing" +) + +func TestInjectClientScript_injectsBeforeBody(t *testing.T) { + body := `

Hello

` + resp := &http.Response{ + Header: http.Header{"Content-Type": []string{"text/html; charset=utf-8"}}, + Body: io.NopCloser(strings.NewReader(body)), + } + + if err := injectClientScript(resp); err != nil { + t.Fatal(err) + } + out, _ := io.ReadAll(resp.Body) + if !strings.Contains(string(out), ``) { + t.Errorf("script not injected before : %s", out) + } +} + +func TestInjectClientScript_appendsWhenNoBodyTag(t *testing.T) { + body := `

No closing body

` + resp := &http.Response{ + Header: http.Header{"Content-Type": []string{"text/html"}}, + Body: io.NopCloser(strings.NewReader(body)), + } + + if err := injectClientScript(resp); err != nil { + t.Fatal(err) + } + out, _ := io.ReadAll(resp.Body) + if !strings.HasSuffix(strings.TrimSpace(string(out)), ``) { + t.Errorf("script not appended: %s", out) + } +} + +func TestInjectClientScript_rewritesAbsolutePaths(t *testing.T) { + body := `` + resp := &http.Response{ + Header: http.Header{"Content-Type": []string{"text/html"}}, + Body: io.NopCloser(strings.NewReader(body)), + } + + if err := injectClientScript(resp); err != nil { + t.Fatal(err) + } + out, _ := io.ReadAll(resp.Body) + s := string(out) + if !strings.Contains(s, `href="/sidecar/proxy/styles.css"`) { + t.Errorf("href not rewritten: %s", s) + } + if !strings.Contains(s, `src="/sidecar/proxy/src/main.ts"`) { + t.Errorf("src not rewritten: %s", s) + } + // client.js src should NOT be double-rewritten + if strings.Contains(s, `/sidecar/proxy/sidecar/`) { + t.Errorf("client.js script tag was incorrectly rewritten: %s", s) + } +} + +func TestInjectClientScript_skipsNonHTML(t *testing.T) { + body := `console.log("hello")` + resp := &http.Response{ + Header: http.Header{"Content-Type": []string{"application/javascript"}}, + Body: io.NopCloser(strings.NewReader(body)), + } + + if err := injectClientScript(resp); err != nil { + t.Fatal(err) + } + out, _ := io.ReadAll(resp.Body) + if strings.Contains(string(out), "sidecar") { + t.Errorf("script injected into non-HTML response") + } +} + +func TestProxyHandler_requiresTarget(t *testing.T) { + handler := NewProxyHandler() + req := httptest.NewRequest("GET", "/sidecar/proxy", nil) + w := httptest.NewRecorder() + handler.ServeHTTP(w, req) + if w.Code != http.StatusBadRequest { + t.Errorf("expected 400, got %d", w.Code) + } +} + +func TestProxyHandler_rejectsNonLocalhost(t *testing.T) { + handler := NewProxyHandler() + req := httptest.NewRequest("GET", "/sidecar/proxy?target=http://evil.com", nil) + w := httptest.NewRecorder() + handler.ServeHTTP(w, req) + if w.Code != http.StatusBadRequest { + t.Errorf("expected 400 for non-localhost target, got %d", w.Code) + } +} +``` + +- [ ] **Step 2: Run test to verify it fails** + +```bash +cd server-go && go test ./internal/sidecar/... +``` +Expected: FAIL — `injectClientScript`, `NewProxyHandler` not defined. + +- [ ] **Step 3: Implement proxy.go** + +Create `server-go/internal/sidecar/proxy.go`: +```go +package sidecar + +import ( + "bytes" + "io" + "net/http" + "net/http/httputil" + "net/url" + "strings" +) + +const ( + scriptTag = `` + cookieName = "__sidecar_target" + cookiePath = "/sidecar/proxy" +) + +// NewProxyHandler returns an http.Handler that: +// - On first load (target query param present): stores target in a cookie and proxies the root. +// - On asset requests (cookie present, path under /sidecar/proxy/*): proxies to the stored target. +// +// HTML responses have: +// 1. Absolute-path src="/" and href="/" attributes rewritten to /sidecar/proxy/ so that +// asset requests stay under the proxy path prefix (where the cookie applies). +// 2. client.js injected before . +// +// V1 limitation: only src/href attributes in HTML are rewritten. JS fetch('/...') calls +// from the app will hit the sidecar, not the target. This works for most Vite/Next.js +// initial page loads; dynamic API calls require a future full-rewrite pass or service worker. +// +// Only localhost targets are accepted. +func NewProxyHandler() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + target := "" + + if t := r.URL.Query().Get("target"); t != "" { + if !isLocalhostURL(t) { + http.Error(w, "target must be a localhost URL", http.StatusBadRequest) + return + } + target = t + http.SetCookie(w, &http.Cookie{ + Name: cookieName, + Value: target, + Path: cookiePath, + SameSite: http.SameSiteStrictMode, + }) + } else if c, err := r.Cookie(cookieName); err == nil { + target = c.Value + } + + if target == "" { + http.Error(w, "target query param required", http.StatusBadRequest) + return + } + + targetURL, err := url.Parse(target) + if err != nil { + http.Error(w, "invalid target URL", http.StatusBadRequest) + return + } + + // Strip /sidecar/proxy prefix to get the subpath for the target + subpath := strings.TrimPrefix(r.URL.Path, "/sidecar/proxy") + if subpath == "" { + subpath = "/" + } + + proxy := httputil.NewSingleHostReverseProxy(targetURL) + proxy.ModifyResponse = injectClientScript + + r2 := r.Clone(r.Context()) + r2.URL = &url.URL{ + Scheme: targetURL.Scheme, + Host: targetURL.Host, + Path: subpath, + RawQuery: r.URL.RawQuery, + } + r2.Host = targetURL.Host + + proxy.ServeHTTP(w, r2) + }) +} + +func isLocalhostURL(raw string) bool { + u, err := url.Parse(raw) + if err != nil { + return false + } + host := u.Hostname() + return host == "localhost" || host == "127.0.0.1" || host == "::1" +} + +func injectClientScript(resp *http.Response) error { + ct := resp.Header.Get("Content-Type") + if !strings.Contains(ct, "text/html") { + return nil + } + + body, err := io.ReadAll(resp.Body) + resp.Body.Close() + if err != nil { + return err + } + + // Rewrite absolute-path asset references so requests stay under /sidecar/proxy/ + // and carry the target cookie. Handles ` + cookieName = "__sidecar_target" + cookiePath = "/sidecar/proxy" +) + +// NewProxyHandler returns an http.Handler that: +// - On first load (target query param present): stores target in a cookie and proxies the root. +// - On asset requests (cookie present, path under /sidecar/proxy/*): proxies to the stored target. +// +// HTML responses have: +// 1. Absolute-path src="/" and href="/" attributes rewritten to /sidecar/proxy/ so that +// asset requests stay under the proxy path prefix (where the cookie applies). +// 2. client.js injected before . +// +// Only localhost targets are accepted. +func NewProxyHandler() http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + target := "" + + if t := r.URL.Query().Get("target"); t != "" { + if !isLocalhostURL(t) { + http.Error(w, "target must be a localhost URL", http.StatusBadRequest) + return + } + target = t + http.SetCookie(w, &http.Cookie{ + Name: cookieName, + Value: target, + Path: cookiePath, + SameSite: http.SameSiteStrictMode, + }) + } else if c, err := r.Cookie(cookieName); err == nil { + target = c.Value + } + + if target == "" { + http.Error(w, "target query param required", http.StatusBadRequest) + return + } + + targetURL, err := url.Parse(target) + if err != nil { + http.Error(w, "invalid target URL", http.StatusBadRequest) + return + } + + // Strip /sidecar/proxy prefix to get the subpath for the target + subpath := strings.TrimPrefix(r.URL.Path, "/sidecar/proxy") + if subpath == "" { + subpath = "/" + } + + proxy := httputil.NewSingleHostReverseProxy(targetURL) + proxy.ModifyResponse = injectClientScript + + r2 := r.Clone(r.Context()) + r2.URL = &url.URL{ + Scheme: targetURL.Scheme, + Host: targetURL.Host, + Path: subpath, + RawQuery: r.URL.RawQuery, + } + r2.Host = targetURL.Host + + proxy.ServeHTTP(w, r2) + }) +} + +func isLocalhostURL(raw string) bool { + u, err := url.Parse(raw) + if err != nil { + return false + } + host := u.Hostname() + return host == "localhost" || host == "127.0.0.1" || host == "::1" +} + +func injectClientScript(resp *http.Response) error { + ct := resp.Header.Get("Content-Type") + if !strings.Contains(ct, "text/html") { + return nil + } + + body, err := io.ReadAll(resp.Body) + resp.Body.Close() + if err != nil { + return err + } + + // Rewrite absolute-path asset references so requests stay under /sidecar/proxy/ + // and carry the target cookie. Handles `) { + t.Errorf("script not injected before : %s", out) + } +} + +func TestInjectClientScript_appendsWhenNoBodyTag(t *testing.T) { + body := `

No closing body

` + resp := &http.Response{ + Header: http.Header{"Content-Type": []string{"text/html"}}, + Body: io.NopCloser(strings.NewReader(body)), + } + + if err := injectClientScript(resp); err != nil { + t.Fatal(err) + } + out, _ := io.ReadAll(resp.Body) + if !strings.HasSuffix(strings.TrimSpace(string(out)), ``) { + t.Errorf("script not appended: %s", out) + } +} + +func TestInjectClientScript_rewritesAbsolutePaths(t *testing.T) { + body := `` + resp := &http.Response{ + Header: http.Header{"Content-Type": []string{"text/html"}}, + Body: io.NopCloser(strings.NewReader(body)), + } + + if err := injectClientScript(resp); err != nil { + t.Fatal(err) + } + out, _ := io.ReadAll(resp.Body) + s := string(out) + if !strings.Contains(s, `href="/sidecar/proxy/styles.css"`) { + t.Errorf("href not rewritten: %s", s) + } + if !strings.Contains(s, `src="/sidecar/proxy/src/main.ts"`) { + t.Errorf("src not rewritten: %s", s) + } + // client.js src should NOT be double-rewritten + if strings.Contains(s, `/sidecar/proxy/sidecar/`) { + t.Errorf("client.js script tag was incorrectly rewritten: %s", s) + } +} + +func TestInjectClientScript_skipsNonHTML(t *testing.T) { + body := `console.log("hello")` + resp := &http.Response{ + Header: http.Header{"Content-Type": []string{"application/javascript"}}, + Body: io.NopCloser(strings.NewReader(body)), + } + + if err := injectClientScript(resp); err != nil { + t.Fatal(err) + } + out, _ := io.ReadAll(resp.Body) + if strings.Contains(string(out), "sidecar") { + t.Errorf("script injected into non-HTML response") + } +} + +func TestProxyHandler_requiresTarget(t *testing.T) { + handler := NewProxyHandler() + req := httptest.NewRequest("GET", "/sidecar/proxy", nil) + w := httptest.NewRecorder() + handler.ServeHTTP(w, req) + if w.Code != http.StatusBadRequest { + t.Errorf("expected 400, got %d", w.Code) + } +} + +func TestProxyHandler_rejectsNonLocalhost(t *testing.T) { + handler := NewProxyHandler() + req := httptest.NewRequest("GET", "/sidecar/proxy?target=http://evil.com", nil) + w := httptest.NewRecorder() + handler.ServeHTTP(w, req) + if w.Code != http.StatusBadRequest { + t.Errorf("expected 400 for non-localhost target, got %d", w.Code) + } +} diff --git a/server-go/internal/sidecar/routes.go b/server-go/internal/sidecar/routes.go new file mode 100644 index 0000000..7d1729e --- /dev/null +++ b/server-go/internal/sidecar/routes.go @@ -0,0 +1,21 @@ +package sidecar + +import ( + "net/http" + + "github.com/go-chi/chi/v5" +) + +// RegisterRoutes mounts all sidecar endpoints under /sidecar. +func RegisterRoutes(r chi.Router, hub *Hub) { + r.Get("/sidecar/client.js", func(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "application/javascript; charset=utf-8") + w.Header().Set("Cache-Control", "no-store") + _, _ = w.Write(ClientJS) + }) + + r.HandleFunc("/sidecar/ws", hub.ServeWS) + + r.Handle("/sidecar/proxy", NewProxyHandler()) + r.Handle("/sidecar/proxy/*", NewProxyHandler()) +} diff --git a/server-go/internal/sidecar/static/client.js b/server-go/internal/sidecar/static/client.js new file mode 100644 index 0000000..a1e8b97 --- /dev/null +++ b/server-go/internal/sidecar/static/client.js @@ -0,0 +1 @@ +// placeholder — overwritten by pnpm build diff --git a/server-go/internal/workspace/router.go b/server-go/internal/workspace/router.go index 2f5a68e..d3bf088 100644 --- a/server-go/internal/workspace/router.go +++ b/server-go/internal/workspace/router.go @@ -72,7 +72,13 @@ func domainStatus(err error) int { return http.StatusInternalServerError } -func RegisterRoutes(r chi.Router, db *sql.DB, session *auth.Session, bus *events.Bus) { +// Refresher is implemented by any type that can trigger a full-page reload +// in connected browser tabs (e.g. the sidecar Hub). +type Refresher interface { + BroadcastRefresh() +} + +func RegisterRoutes(r chi.Router, db *sql.DB, session *auth.Session, bus *events.Bus, refresher ...Refresher) { r.Use(auth.RequireSession(session)) // Projects @@ -304,6 +310,9 @@ func RegisterRoutes(r chi.Router, db *sql.DB, session *auth.Session, bus *events return } jsonResp(w, map[string]bool{"ok": true}, http.StatusOK) + for _, rf := range refresher { + rf.BroadcastRefresh() + } }) r.Post("/worktrees/{id}/files", func(w http.ResponseWriter, r *http.Request) { diff --git a/sidecar-client/dist/client.js b/sidecar-client/dist/client.js new file mode 100644 index 0000000..6454fe4 --- /dev/null +++ b/sidecar-client/dist/client.js @@ -0,0 +1,39 @@ +(function(){"use strict";let uA=Object.getPrototypeOf,zA,$A,z,yA,Et={isConnected:1},On=1e3,He,Fr={},Mn=uA(Et),Ht=uA(uA),mA,pt=(e,A,t,r)=>(e??(r?setTimeout(t,r):queueMicrotask(t),new Set)).add(A),It=(e,A,t)=>{let r=z;z=A;try{return e(t)}catch(B){return console.error(B),t}finally{z=r}},pe=e=>e.filter(A=>{var t;return(t=A._dom)==null?void 0:t.isConnected}),vt=e=>He=pt(He,e,()=>{for(let A of He)A._bindings=pe(A._bindings),A._listeners=pe(A._listeners);He=mA},On),Ie={get val(){var e;return(e=z==null?void 0:z._getters)==null||e.add(this),this.rawVal},get oldVal(){var e;return(e=z==null?void 0:z._getters)==null||e.add(this),this._oldVal},set val(e){var A;(A=z==null?void 0:z._setters)==null||A.add(this),e!==this.rawVal&&(this.rawVal=e,this._bindings.length+this._listeners.length?($A==null||$A.add(this),zA=pt(zA,this,Gn)):this._oldVal=e)}},yt=e=>({__proto__:Ie,rawVal:e,_oldVal:e,_bindings:[],_listeners:[]}),Ae=(e,A)=>{let t={_getters:new Set,_setters:new Set},r={f:e},B=yA;yA=[];let n=It(e,t,A);n=(n??document).nodeType?n:new Text(n);for(let s of t._getters)t._setters.has(s)||(vt(s),s._bindings.push(r));for(let s of yA)s._dom=n;return yA=B,r._dom=n},hr=(e,A=yt(),t)=>{let r={_getters:new Set,_setters:new Set},B={f:e,s:A};B._dom=t??(yA==null?void 0:yA.push(B))??Et,A.val=It(e,r,A.rawVal);for(let n of r._getters)r._setters.has(n)||(vt(n),n._listeners.push(B));return A},mt=(e,...A)=>{for(let t of A.flat(1/0)){let r=uA(t??0),B=r===Ie?Ae(()=>t.val):r===Ht?Ae(t):t;B!=mA&&e.append(B)}return e},Kt=(e,A,...t)=>{var i;let[{is:r,...B},...n]=uA(t[0]??0)===Mn?t:[{},...t],s=e?document.createElementNS(e,A,{is:r}):document.createElement(A,{is:r});for(let[a,o]of Object.entries(B)){let Q=l=>l?Object.getOwnPropertyDescriptor(l,a)??Q(uA(l)):mA,g=A+","+a,c=Fr[g]??(Fr[g]=((i=Q(uA(s)))==null?void 0:i.set)??0),u=a.startsWith("on")?(l,H)=>{let F=a.slice(2);s.removeEventListener(F,H),s.addEventListener(F,l)}:c?c.bind(s):s.setAttribute.bind(s,a),w=uA(o??0);a.startsWith("on")||w===Ht&&(o=hr(o),w=Ie),w===Ie?Ae(()=>(u(o.val,o._oldVal),s)):u(o)}return mt(s,n)},Lt=e=>({get:(A,t)=>Kt.bind(mA,e,t)}),bt=(e,A)=>A?A!==e&&e.replaceWith(A):e.remove(),Gn=()=>{let e=0,A=[...zA].filter(r=>r.rawVal!==r._oldVal);do{$A=new Set;for(let r of new Set(A.flatMap(B=>B._listeners=pe(B._listeners))))hr(r.f,r.s,r._dom),r._dom=mA}while(++e<100&&(A=[...$A]).length);let t=[...zA].filter(r=>r.rawVal!==r._oldVal);zA=mA;for(let r of new Set(t.flatMap(B=>B._bindings=pe(B._bindings))))bt(r._dom,Ae(r.f,r._dom)),r._dom=mA;for(let r of t)r._oldVal=r.rawVal};const dr={tags:new Proxy(e=>new Proxy(Kt,Lt(e)),Lt()),hydrate:(e,A)=>bt(e,Ae(A,e)),add:mt,state:yt,derive:hr},Rn=` + :host { all: initial; } + .pill { + display: flex; align-items: center; gap: 8px; + background: #1e1e2e; border-radius: 6px; + padding: 6px 12px; cursor: pointer; + font-family: monospace; font-size: 12px; + box-shadow: 0 2px 8px rgba(0,0,0,0.4); + user-select: none; + } + .dot { + width: 8px; height: 8px; border-radius: 50%; + transition: background 0.15s; + } + .dot.off { background: #6c7086; } + .dot.on { background: #a6e3a1; } + .label { color: #cdd6f4; } +`;function Vn(e){const{div:A,span:t,style:r}=dr.tags,B=dr.state(!1),n=document.createElement("div");n.setAttribute("data-sidecar-pill",""),n.style.cssText="position:fixed;bottom:16px;left:16px;z-index:2147483647;pointer-events:auto",document.body.appendChild(n);const s=n.attachShadow({mode:"open"}),i=A({class:"pill",onclick:()=>{B.val=!B.val,e(B.val)}},t({class:()=>`dot ${B.val?"on":"off"}`}),t({class:"label"},"Select"));return dr.add(s,r(Rn),i),{setActive(a){B.val=a}}}const Nn=/^[a-z]+-(?=[a-z0-9]*\d)[a-z0-9]{4,}$/i,_n=2;function Xn(e){if(e===document.body)return"body";const A=[];let t=e;for(;t&&t!==document.body;){if(t.id){A.unshift(`#${t.id}`);break}const r=t.tagName.toLowerCase(),B=Array.from(t.classList).filter(s=>!Nn.test(s)).slice(0,_n),n=B.length>0?`${r}.${B.join(".")}`:r;A.unshift(n),t=t.parentElement}return A.join(" > ")||e.tagName.toLowerCase()}/*! + * html2canvas 1.4.1 + * Copyright (c) 2022 Niklas von Hertzen + * Released under MIT License + *//*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */var Er=function(e,A){return Er=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,r){t.__proto__=r}||function(t,r){for(var B in r)Object.prototype.hasOwnProperty.call(r,B)&&(t[B]=r[B])},Er(e,A)};function tA(e,A){if(typeof A!="function"&&A!==null)throw new TypeError("Class extends value "+String(A)+" is not a constructor or null");Er(e,A);function t(){this.constructor=e}e.prototype=A===null?Object.create(A):(t.prototype=A.prototype,new t)}var Hr=function(){return Hr=Object.assign||function(A){for(var t,r=1,B=arguments.length;r0&&n[n.length-1])&&(o[0]===6||o[0]===2)){t=0;continue}if(o[0]===3&&(!n||o[1]>n[0]&&o[1]=55296&&B<=56319&&t>10)+55296,s%1024+56320)),(B+1===t||r.length>16384)&&(n+=String.fromCharCode.apply(String,r),r.length=0)}return n},Dt="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",Jn=typeof Uint8Array>"u"?[]:new Uint8Array(256),Ke=0;Ke"u"?[]:new Uint8Array(256),Le=0;Le>4,Q[B++]=(s&15)<<4|i>>2,Q[B++]=(i&3)<<6|a&63;return o},Yn=function(e){for(var A=e.length,t=[],r=0;r>KA,qn=1<>KA,zn=St+jn,$n=zn,As=32,es=$n+As,rs=65536>>pr,ts=1<=0){if(A<55296||A>56319&&A<=65535)return t=this.index[A>>KA],t=(t<>KA)],t=(t<>pr),t=this.index[t],t+=A>>KA&Bs,t=this.index[t],t=(t<"u"?[]:new Uint8Array(256),be=0;beMt?(B.push(!0),i-=Mt):B.push(!1),["normal","auto","loose"].indexOf(A)!==-1&&[8208,8211,12316,12448].indexOf(n)!==-1)return r.push(s),t.push(Kr);if(i===gs||i===yr){if(s===0)return r.push(s),t.push(LA);var a=t[s-1];return Fs.indexOf(a)===-1?(r.push(r[s-1]),t.push(a)):(r.push(s),t.push(LA))}if(r.push(s),i===Cs)return t.push(A==="strict"?Lr:ae);if(i===Jt||i===us)return t.push(LA);if(i===fs)return n>=131072&&n<=196605||n>=196608&&n<=262141?t.push(ae):t.push(LA);t.push(i)}),[r,t,B]},Rr=function(e,A,t,r){var B=r[t];if(Array.isArray(e)?e.indexOf(B)!==-1:e===B)for(var n=t;n<=r.length;){n++;var s=r[n];if(s===A)return!0;if(s!==CA)break}if(B===CA)for(var n=t;n>0;){n--;var i=r[n];if(Array.isArray(e)?e.indexOf(i)!==-1:e===i)for(var a=t;a<=r.length;){a++;var s=r[a];if(s===A)return!0;if(s!==CA)break}if(i!==CA)break}return!1},qt=function(e,A){for(var t=e;t>=0;){var r=A[t];if(r===CA)t--;else return r}return 0},Es=function(e,A,t,r,B){if(t[r]===0)return I;var n=r-1;if(Array.isArray(B)&&B[n]===!0)return I;var s=n-1,i=n+1,a=A[n],o=s>=0?A[s]:0,Q=A[i];if(a===Gt&&Q===Rt)return I;if(Gr.indexOf(a)!==-1)return kt;if(Gr.indexOf(Q)!==-1||Yt.indexOf(Q)!==-1)return I;if(qt(n,A)===Nt)return Me;if(Mr.get(e[n])===yr||(a===xe||a===Se)&&Mr.get(e[i])===yr||a===Vt||Q===Vt||a===_t||[CA,mr,re].indexOf(a)===-1&&Q===_t||[De,te,ls,GA,RA].indexOf(Q)!==-1||qt(n,A)===Be||Rr(br,Be,n,A)||Rr([De,te],Lr,n,A)||Rr(Xt,Xt,n,A))return I;if(a===CA)return Me;if(a===br||Q===br)return I;if(Q===Kr||a===Kr)return Me;if([mr,re,Lr].indexOf(Q)!==-1||a===ws||o===Sr&&hs.indexOf(a)!==-1||a===RA&&Q===Sr||Q===Pt||QA.indexOf(Q)!==-1&&a===q||QA.indexOf(a)!==-1&&Q===q||a===se&&[ae,xe,Se].indexOf(Q)!==-1||[ae,xe,Se].indexOf(a)!==-1&&Q===ne||QA.indexOf(a)!==-1&&Wt.indexOf(Q)!==-1||Wt.indexOf(a)!==-1&&QA.indexOf(Q)!==-1||[se,ne].indexOf(a)!==-1&&(Q===q||[Be,re].indexOf(Q)!==-1&&A[i+1]===q)||[Be,re].indexOf(a)!==-1&&Q===q||a===q&&[q,RA,GA].indexOf(Q)!==-1)return I;if([q,RA,GA,De,te].indexOf(Q)!==-1)for(var g=n;g>=0;){var c=A[g];if(c===q)return I;if([RA,GA].indexOf(c)!==-1)g--;else break}if([se,ne].indexOf(Q)!==-1)for(var g=[De,te].indexOf(a)!==-1?s:n;g>=0;){var c=A[g];if(c===q)return I;if([RA,GA].indexOf(c)!==-1)g--;else break}if(Tr===a&&[Tr,Te,Dr,xr].indexOf(Q)!==-1||[Te,Dr].indexOf(a)!==-1&&[Te,Oe].indexOf(Q)!==-1||[Oe,xr].indexOf(a)!==-1&&Q===Oe||Zt.indexOf(a)!==-1&&[Pt,ne].indexOf(Q)!==-1||Zt.indexOf(Q)!==-1&&a===se||QA.indexOf(a)!==-1&&QA.indexOf(Q)!==-1||a===GA&&QA.indexOf(Q)!==-1||QA.concat(q).indexOf(a)!==-1&&Q===Be&&Us.indexOf(e[i])===-1||QA.concat(q).indexOf(Q)!==-1&&a===te)return I;if(a===Or&&Q===Or){for(var u=t[n],w=1;u>0&&(u--,A[u]===Or);)w++;if(w%2!==0)return I}return a===xe&&Q===Se?I:Me},Hs=function(e,A){A||(A={lineBreak:"normal",wordBreak:"normal"});var t=ds(e,A.lineBreak),r=t[0],B=t[1],n=t[2];(A.wordBreak==="break-all"||A.wordBreak==="break-word")&&(B=B.map(function(i){return[q,LA,Jt].indexOf(i)!==-1?ae:i}));var s=A.wordBreak==="keep-all"?n.map(function(i,a){return i&&e[a]>=19968&&e[a]<=40959}):void 0;return[r,B,s]},ps=(function(){function e(A,t,r,B){this.codePoints=A,this.required=t===kt,this.start=r,this.end=B}return e.prototype.slice=function(){return S.apply(void 0,this.codePoints.slice(this.start,this.end))},e})(),Is=function(e,A){var t=me(e),r=Hs(t,A),B=r[0],n=r[1],s=r[2],i=t.length,a=0,o=0;return{next:function(){if(o>=i)return{done:!0,value:null};for(var Q=I;o=eB&&e<=57},na=function(e){return e>=55296&&e<=57343},VA=function(e){return P(e)||e>=BB&&e<=sB||e>=rB&&e<=Aa},sa=function(e){return e>=rB&&e<=ra},aa=function(e){return e>=BB&&e<=Ba},ia=function(e){return sa(e)||aa(e)},oa=function(e){return e>=Ps},Xe=function(e){return e===Ge||e===ms||e===Ks},Pe=function(e){return ia(e)||oa(e)||e===xs},aB=function(e){return Pe(e)||P(e)||e===k},Qa=function(e){return e>=Ws&&e<=Zs||e===qs||e>=js&&e<=zs||e===$s},fA=function(e,A){return e!==oe?!1:A!==Ge},Je=function(e,A,t){return e===k?Pe(A)||fA(A,t):Pe(e)?!0:!!(e===oe&&fA(e,A))},Nr=function(e,A,t){return e===bA||e===k?P(A)?!0:A===ce&&P(t):P(e===ce?A:e)},ga=function(e){var A=0,t=1;(e[A]===bA||e[A]===k)&&(e[A]===k&&(t=-1),A++);for(var r=[];P(e[A]);)r.push(e[A++]);var B=r.length?parseInt(S.apply(void 0,r),10):0;e[A]===ce&&A++;for(var n=[];P(e[A]);)n.push(e[A++]);var s=n.length,i=s?parseInt(S.apply(void 0,n),10):0;(e[A]===nB||e[A]===tB)&&A++;var a=1;(e[A]===bA||e[A]===k)&&(e[A]===k&&(a=-1),A++);for(var o=[];P(e[A]);)o.push(e[A++]);var Q=o.length?parseInt(S.apply(void 0,o),10):0;return t*(B+i*Math.pow(10,-s))*Math.pow(10,a*Q)},ca={type:2},wa={type:3},la={type:4},ua={type:13},Ca={type:8},fa={type:21},Ua={type:9},Fa={type:10},ha={type:11},da={type:12},Ea={type:14},ke={type:23},Ha={type:1},pa={type:25},Ia={type:24},va={type:26},ya={type:27},ma={type:28},Ka={type:29},La={type:31},_r={type:32},iB=(function(){function e(){this._value=[]}return e.prototype.write=function(A){this._value=this._value.concat(me(A))},e.prototype.read=function(){for(var A=[],t=this.consumeToken();t!==_r;)A.push(t),t=this.consumeToken();return A},e.prototype.consumeToken=function(){var A=this.consumeCodePoint();switch(A){case Re:return this.consumeStringToken(Re);case Ls:var t=this.peekCodePoint(0),r=this.peekCodePoint(1),B=this.peekCodePoint(2);if(aB(t)||fA(r,B)){var n=Je(t,r,B)?ys:vs,s=this.consumeName();return{type:5,value:s,flags:n}}break;case bs:if(this.peekCodePoint(0)===Qe)return this.consumeCodePoint(),ua;break;case Ve:return this.consumeStringToken(Ve);case Ne:return ca;case ge:return wa;case Vr:if(this.peekCodePoint(0)===Qe)return this.consumeCodePoint(),Ea;break;case bA:if(Nr(A,this.peekCodePoint(0),this.peekCodePoint(1)))return this.reconsumeCodePoint(A),this.consumeNumericToken();break;case Js:return la;case k:var i=A,a=this.peekCodePoint(0),o=this.peekCodePoint(1);if(Nr(i,a,o))return this.reconsumeCodePoint(A),this.consumeNumericToken();if(Je(i,a,o))return this.reconsumeCodePoint(A),this.consumeIdentLikeToken();if(a===k&&o===Os)return this.consumeCodePoint(),this.consumeCodePoint(),Ia;break;case ce:if(Nr(A,this.peekCodePoint(0),this.peekCodePoint(1)))return this.reconsumeCodePoint(A),this.consumeNumericToken();break;case zt:if(this.peekCodePoint(0)===Vr)for(this.consumeCodePoint();;){var Q=this.consumeCodePoint();if(Q===Vr&&(Q=this.consumeCodePoint(),Q===zt))return this.consumeToken();if(Q===nA)return this.consumeToken()}break;case ks:return va;case Ys:return ya;case Ts:if(this.peekCodePoint(0)===Ss&&this.peekCodePoint(1)===k&&this.peekCodePoint(2)===k)return this.consumeCodePoint(),this.consumeCodePoint(),pa;break;case Ms:var g=this.peekCodePoint(0),c=this.peekCodePoint(1),u=this.peekCodePoint(2);if(Je(g,c,u)){var s=this.consumeName();return{type:7,value:s}}break;case Gs:return ma;case oe:if(fA(A,this.peekCodePoint(0)))return this.reconsumeCodePoint(A),this.consumeIdentLikeToken();break;case Rs:return Ka;case Vs:if(this.peekCodePoint(0)===Qe)return this.consumeCodePoint(),Ca;break;case Ns:return ha;case _s:return da;case ea:case ta:var w=this.peekCodePoint(0),l=this.peekCodePoint(1);return w===bA&&(VA(l)||l===_e)&&(this.consumeCodePoint(),this.consumeUnicodeRangeToken()),this.reconsumeCodePoint(A),this.consumeIdentLikeToken();case $t:if(this.peekCodePoint(0)===Qe)return this.consumeCodePoint(),Ua;if(this.peekCodePoint(0)===$t)return this.consumeCodePoint(),fa;break;case Xs:if(this.peekCodePoint(0)===Qe)return this.consumeCodePoint(),Fa;break;case nA:return _r}return Xe(A)?(this.consumeWhiteSpace(),La):P(A)?(this.reconsumeCodePoint(A),this.consumeNumericToken()):Pe(A)?(this.reconsumeCodePoint(A),this.consumeIdentLikeToken()):{type:6,value:S(A)}},e.prototype.consumeCodePoint=function(){var A=this._value.shift();return typeof A>"u"?-1:A},e.prototype.reconsumeCodePoint=function(A){this._value.unshift(A)},e.prototype.peekCodePoint=function(A){return A>=this._value.length?-1:this._value[A]},e.prototype.consumeUnicodeRangeToken=function(){for(var A=[],t=this.consumeCodePoint();VA(t)&&A.length<6;)A.push(t),t=this.consumeCodePoint();for(var r=!1;t===_e&&A.length<6;)A.push(t),t=this.consumeCodePoint(),r=!0;if(r){var B=parseInt(S.apply(void 0,A.map(function(a){return a===_e?eB:a})),16),n=parseInt(S.apply(void 0,A.map(function(a){return a===_e?sB:a})),16);return{type:30,start:B,end:n}}var s=parseInt(S.apply(void 0,A),16);if(this.peekCodePoint(0)===k&&VA(this.peekCodePoint(1))){this.consumeCodePoint(),t=this.consumeCodePoint();for(var i=[];VA(t)&&i.length<6;)i.push(t),t=this.consumeCodePoint();var n=parseInt(S.apply(void 0,i),16);return{type:30,start:s,end:n}}else return{type:30,start:s,end:s}},e.prototype.consumeIdentLikeToken=function(){var A=this.consumeName();return A.toLowerCase()==="url"&&this.peekCodePoint(0)===Ne?(this.consumeCodePoint(),this.consumeUrlToken()):this.peekCodePoint(0)===Ne?(this.consumeCodePoint(),{type:19,value:A}):{type:20,value:A}},e.prototype.consumeUrlToken=function(){var A=[];if(this.consumeWhiteSpace(),this.peekCodePoint(0)===nA)return{type:22,value:""};var t=this.peekCodePoint(0);if(t===Ve||t===Re){var r=this.consumeStringToken(this.consumeCodePoint());return r.type===0&&(this.consumeWhiteSpace(),this.peekCodePoint(0)===nA||this.peekCodePoint(0)===ge)?(this.consumeCodePoint(),{type:22,value:r.value}):(this.consumeBadUrlRemnants(),ke)}for(;;){var B=this.consumeCodePoint();if(B===nA||B===ge)return{type:22,value:S.apply(void 0,A)};if(Xe(B))return this.consumeWhiteSpace(),this.peekCodePoint(0)===nA||this.peekCodePoint(0)===ge?(this.consumeCodePoint(),{type:22,value:S.apply(void 0,A)}):(this.consumeBadUrlRemnants(),ke);if(B===Re||B===Ve||B===Ne||Qa(B))return this.consumeBadUrlRemnants(),ke;if(B===oe)if(fA(B,this.peekCodePoint(0)))A.push(this.consumeEscapedCodePoint());else return this.consumeBadUrlRemnants(),ke;else A.push(B)}},e.prototype.consumeWhiteSpace=function(){for(;Xe(this.peekCodePoint(0));)this.consumeCodePoint()},e.prototype.consumeBadUrlRemnants=function(){for(;;){var A=this.consumeCodePoint();if(A===ge||A===nA)return;fA(A,this.peekCodePoint(0))&&this.consumeEscapedCodePoint()}},e.prototype.consumeStringSlice=function(A){for(var t=5e4,r="";A>0;){var B=Math.min(t,A);r+=S.apply(void 0,this._value.splice(0,B)),A-=B}return this._value.shift(),r},e.prototype.consumeStringToken=function(A){var t="",r=0;do{var B=this._value[r];if(B===nA||B===void 0||B===A)return t+=this.consumeStringSlice(r),{type:0,value:t};if(B===Ge)return this._value.splice(0,r),Ha;if(B===oe){var n=this._value[r+1];n!==nA&&n!==void 0&&(n===Ge?(t+=this.consumeStringSlice(r),r=-1,this._value.shift()):fA(B,n)&&(t+=this.consumeStringSlice(r),t+=S(this.consumeEscapedCodePoint()),r=-1))}r++}while(!0)},e.prototype.consumeNumber=function(){var A=[],t=ie,r=this.peekCodePoint(0);for((r===bA||r===k)&&A.push(this.consumeCodePoint());P(this.peekCodePoint(0));)A.push(this.consumeCodePoint());r=this.peekCodePoint(0);var B=this.peekCodePoint(1);if(r===ce&&P(B))for(A.push(this.consumeCodePoint(),this.consumeCodePoint()),t=jt;P(this.peekCodePoint(0));)A.push(this.consumeCodePoint());r=this.peekCodePoint(0),B=this.peekCodePoint(1);var n=this.peekCodePoint(2);if((r===nB||r===tB)&&((B===bA||B===k)&&P(n)||P(B)))for(A.push(this.consumeCodePoint(),this.consumeCodePoint()),t=jt;P(this.peekCodePoint(0));)A.push(this.consumeCodePoint());return[ga(A),t]},e.prototype.consumeNumericToken=function(){var A=this.consumeNumber(),t=A[0],r=A[1],B=this.peekCodePoint(0),n=this.peekCodePoint(1),s=this.peekCodePoint(2);if(Je(B,n,s)){var i=this.consumeName();return{type:15,number:t,flags:r,unit:i}}return B===Ds?(this.consumeCodePoint(),{type:16,number:t,flags:r}):{type:17,number:t,flags:r}},e.prototype.consumeEscapedCodePoint=function(){var A=this.consumeCodePoint();if(VA(A)){for(var t=S(A);VA(this.peekCodePoint(0))&&t.length<6;)t+=S(this.consumeCodePoint());Xe(this.peekCodePoint(0))&&this.consumeCodePoint();var r=parseInt(t,16);return r===0||na(r)||r>1114111?AB:r}return A===nA?AB:A},e.prototype.consumeName=function(){for(var A="";;){var t=this.consumeCodePoint();if(aB(t))A+=S(t);else if(fA(t,this.peekCodePoint(0)))A+=S(this.consumeEscapedCodePoint());else return this.reconsumeCodePoint(t),A}},e})(),oB=(function(){function e(A){this._tokens=A}return e.create=function(A){var t=new iB;return t.write(A),new e(t.read())},e.parseValue=function(A){return e.create(A).parseComponentValue()},e.parseValues=function(A){return e.create(A).parseComponentValues()},e.prototype.parseComponentValue=function(){for(var A=this.consumeToken();A.type===31;)A=this.consumeToken();if(A.type===32)throw new SyntaxError("Error parsing CSS component value, unexpected EOF");this.reconsumeToken(A);var t=this.consumeComponentValue();do A=this.consumeToken();while(A.type===31);if(A.type===32)return t;throw new SyntaxError("Error parsing CSS component value, multiple values found when expecting only one")},e.prototype.parseComponentValues=function(){for(var A=[];;){var t=this.consumeComponentValue();if(t.type===32)return A;A.push(t),A.push()}},e.prototype.consumeComponentValue=function(){var A=this.consumeToken();switch(A.type){case 11:case 28:case 2:return this.consumeSimpleBlock(A.type);case 19:return this.consumeFunction(A)}return A},e.prototype.consumeSimpleBlock=function(A){for(var t={type:A,values:[]},r=this.consumeToken();;){if(r.type===32||Da(r,A))return t;this.reconsumeToken(r),t.values.push(this.consumeComponentValue()),r=this.consumeToken()}},e.prototype.consumeFunction=function(A){for(var t={name:A.value,values:[],type:18};;){var r=this.consumeToken();if(r.type===32||r.type===3)return t;this.reconsumeToken(r),t.values.push(this.consumeComponentValue())}},e.prototype.consumeToken=function(){var A=this._tokens.shift();return typeof A>"u"?_r:A},e.prototype.reconsumeToken=function(A){this._tokens.unshift(A)},e})(),we=function(e){return e.type===15},NA=function(e){return e.type===17},L=function(e){return e.type===20},ba=function(e){return e.type===0},Xr=function(e,A){return L(e)&&e.value===A},QB=function(e){return e.type!==31},_A=function(e){return e.type!==31&&e.type!==4},sA=function(e){var A=[],t=[];return e.forEach(function(r){if(r.type===4){if(t.length===0)throw new Error("Error parsing function args, zero tokens for arg");A.push(t),t=[];return}r.type!==31&&t.push(r)}),t.length&&A.push(t),A},Da=function(e,A){return A===11&&e.type===12||A===28&&e.type===29?!0:A===2&&e.type===3},UA=function(e){return e.type===17||e.type===15},O=function(e){return e.type===16||UA(e)},gB=function(e){return e.length>1?[e[0],e[1]]:[e[0]]},V={type:17,number:0,flags:ie},Pr={type:16,number:50,flags:ie},FA={type:16,number:100,flags:ie},le=function(e,A,t){var r=e[0],B=e[1];return[D(r,A),D(typeof B<"u"?B:r,t)]},D=function(e,A){if(e.type===16)return e.number/100*A;if(we(e))switch(e.unit){case"rem":case"em":return 16*e.number;case"px":default:return e.number}return e.number},cB="deg",wB="grad",lB="rad",uB="turn",Ye={name:"angle",parse:function(e,A){if(A.type===15)switch(A.unit){case cB:return Math.PI*A.number/180;case wB:return Math.PI/200*A.number;case lB:return A.number;case uB:return Math.PI*2*A.number}throw new Error("Unsupported angle type")}},CB=function(e){return e.type===15&&(e.unit===cB||e.unit===wB||e.unit===lB||e.unit===uB)},fB=function(e){var A=e.filter(L).map(function(t){return t.value}).join(" ");switch(A){case"to bottom right":case"to right bottom":case"left top":case"top left":return[V,V];case"to top":case"bottom":return $(0);case"to bottom left":case"to left bottom":case"right top":case"top right":return[V,FA];case"to right":case"left":return $(90);case"to top left":case"to left top":case"right bottom":case"bottom right":return[FA,FA];case"to bottom":case"top":return $(180);case"to top right":case"to right top":case"left bottom":case"bottom left":return[FA,V];case"to left":case"right":return $(270)}return 0},$=function(e){return Math.PI*e/180},hA={name:"color",parse:function(e,A){if(A.type===18){var t=xa[A.name];if(typeof t>"u")throw new Error('Attempting to parse an unsupported color function "'+A.name+'"');return t(e,A.values)}if(A.type===5){if(A.value.length===3){var r=A.value.substring(0,1),B=A.value.substring(1,2),n=A.value.substring(2,3);return EA(parseInt(r+r,16),parseInt(B+B,16),parseInt(n+n,16),1)}if(A.value.length===4){var r=A.value.substring(0,1),B=A.value.substring(1,2),n=A.value.substring(2,3),s=A.value.substring(3,4);return EA(parseInt(r+r,16),parseInt(B+B,16),parseInt(n+n,16),parseInt(s+s,16)/255)}if(A.value.length===6){var r=A.value.substring(0,2),B=A.value.substring(2,4),n=A.value.substring(4,6);return EA(parseInt(r,16),parseInt(B,16),parseInt(n,16),1)}if(A.value.length===8){var r=A.value.substring(0,2),B=A.value.substring(2,4),n=A.value.substring(4,6),s=A.value.substring(6,8);return EA(parseInt(r,16),parseInt(B,16),parseInt(n,16),parseInt(s,16)/255)}}if(A.type===20){var i=gA[A.value.toUpperCase()];if(typeof i<"u")return i}return gA.TRANSPARENT}},dA=function(e){return(255&e)===0},R=function(e){var A=255&e,t=255&e>>8,r=255&e>>16,B=255&e>>24;return A<255?"rgba("+B+","+r+","+t+","+A/255+")":"rgb("+B+","+r+","+t+")"},EA=function(e,A,t,r){return(e<<24|A<<16|t<<8|Math.round(r*255)<<0)>>>0},UB=function(e,A){if(e.type===17)return e.number;if(e.type===16){var t=A===3?1:255;return A===3?e.number/100*t:Math.round(e.number/100*t)}return 0},FB=function(e,A){var t=A.filter(_A);if(t.length===3){var r=t.map(UB),B=r[0],n=r[1],s=r[2];return EA(B,n,s,1)}if(t.length===4){var i=t.map(UB),B=i[0],n=i[1],s=i[2],a=i[3];return EA(B,n,s,a)}return 0};function Jr(e,A,t){return t<0&&(t+=1),t>=1&&(t-=1),t<1/6?(A-e)*t*6+e:t<1/2?A:t<2/3?(A-e)*6*(2/3-t)+e:e}var hB=function(e,A){var t=A.filter(_A),r=t[0],B=t[1],n=t[2],s=t[3],i=(r.type===17?$(r.number):Ye.parse(e,r))/(Math.PI*2),a=O(B)?B.number/100:0,o=O(n)?n.number/100:0,Q=typeof s<"u"&&O(s)?D(s,1):1;if(a===0)return EA(o*255,o*255,o*255,1);var g=o<=.5?o*(a+1):o+a-o*a,c=o*2-g,u=Jr(c,g,i+1/3),w=Jr(c,g,i),l=Jr(c,g,i-1/3);return EA(u*255,w*255,l*255,Q)},xa={hsl:hB,hsla:hB,rgb:FB,rgba:FB},ue=function(e,A){return hA.parse(e,oB.create(A).parseComponentValue())},gA={ALICEBLUE:4042850303,ANTIQUEWHITE:4209760255,AQUA:16777215,AQUAMARINE:2147472639,AZURE:4043309055,BEIGE:4126530815,BISQUE:4293182719,BLACK:255,BLANCHEDALMOND:4293643775,BLUE:65535,BLUEVIOLET:2318131967,BROWN:2771004159,BURLYWOOD:3736635391,CADETBLUE:1604231423,CHARTREUSE:2147418367,CHOCOLATE:3530104575,CORAL:4286533887,CORNFLOWERBLUE:1687547391,CORNSILK:4294499583,CRIMSON:3692313855,CYAN:16777215,DARKBLUE:35839,DARKCYAN:9145343,DARKGOLDENROD:3095837695,DARKGRAY:2846468607,DARKGREEN:6553855,DARKGREY:2846468607,DARKKHAKI:3182914559,DARKMAGENTA:2332068863,DARKOLIVEGREEN:1433087999,DARKORANGE:4287365375,DARKORCHID:2570243327,DARKRED:2332033279,DARKSALMON:3918953215,DARKSEAGREEN:2411499519,DARKSLATEBLUE:1211993087,DARKSLATEGRAY:793726975,DARKSLATEGREY:793726975,DARKTURQUOISE:13554175,DARKVIOLET:2483082239,DEEPPINK:4279538687,DEEPSKYBLUE:12582911,DIMGRAY:1768516095,DIMGREY:1768516095,DODGERBLUE:512819199,FIREBRICK:2988581631,FLORALWHITE:4294635775,FORESTGREEN:579543807,FUCHSIA:4278255615,GAINSBORO:3705462015,GHOSTWHITE:4177068031,GOLD:4292280575,GOLDENROD:3668254975,GRAY:2155905279,GREEN:8388863,GREENYELLOW:2919182335,GREY:2155905279,HONEYDEW:4043305215,HOTPINK:4285117695,INDIANRED:3445382399,INDIGO:1258324735,IVORY:4294963455,KHAKI:4041641215,LAVENDER:3873897215,LAVENDERBLUSH:4293981695,LAWNGREEN:2096890111,LEMONCHIFFON:4294626815,LIGHTBLUE:2916673279,LIGHTCORAL:4034953471,LIGHTCYAN:3774873599,LIGHTGOLDENRODYELLOW:4210742015,LIGHTGRAY:3553874943,LIGHTGREEN:2431553791,LIGHTGREY:3553874943,LIGHTPINK:4290167295,LIGHTSALMON:4288707327,LIGHTSEAGREEN:548580095,LIGHTSKYBLUE:2278488831,LIGHTSLATEGRAY:2005441023,LIGHTSLATEGREY:2005441023,LIGHTSTEELBLUE:2965692159,LIGHTYELLOW:4294959359,LIME:16711935,LIMEGREEN:852308735,LINEN:4210091775,MAGENTA:4278255615,MAROON:2147483903,MEDIUMAQUAMARINE:1724754687,MEDIUMBLUE:52735,MEDIUMORCHID:3126187007,MEDIUMPURPLE:2473647103,MEDIUMSEAGREEN:1018393087,MEDIUMSLATEBLUE:2070474495,MEDIUMSPRINGGREEN:16423679,MEDIUMTURQUOISE:1221709055,MEDIUMVIOLETRED:3340076543,MIDNIGHTBLUE:421097727,MINTCREAM:4127193855,MISTYROSE:4293190143,MOCCASIN:4293178879,NAVAJOWHITE:4292783615,NAVY:33023,OLDLACE:4260751103,OLIVE:2155872511,OLIVEDRAB:1804477439,ORANGE:4289003775,ORANGERED:4282712319,ORCHID:3664828159,PALEGOLDENROD:4008225535,PALEGREEN:2566625535,PALETURQUOISE:2951671551,PALEVIOLETRED:3681588223,PAPAYAWHIP:4293907967,PEACHPUFF:4292524543,PERU:3448061951,PINK:4290825215,PLUM:3718307327,POWDERBLUE:2967529215,PURPLE:2147516671,REBECCAPURPLE:1714657791,RED:4278190335,ROSYBROWN:3163525119,ROYALBLUE:1097458175,SADDLEBROWN:2336560127,SALMON:4202722047,SANDYBROWN:4104413439,SEAGREEN:780883967,SEASHELL:4294307583,SIENNA:2689740287,SILVER:3233857791,SKYBLUE:2278484991,SLATEBLUE:1784335871,SLATEGRAY:1887473919,SLATEGREY:1887473919,SNOW:4294638335,SPRINGGREEN:16744447,STEELBLUE:1182971135,TAN:3535047935,TEAL:8421631,THISTLE:3636451583,TOMATO:4284696575,TRANSPARENT:0,TURQUOISE:1088475391,VIOLET:4001558271,WHEAT:4125012991,WHITE:4294967295,WHITESMOKE:4126537215,YELLOW:4294902015,YELLOWGREEN:2597139199},Sa={name:"background-clip",initialValue:"border-box",prefix:!1,type:1,parse:function(e,A){return A.map(function(t){if(L(t))switch(t.value){case"padding-box":return 1;case"content-box":return 2}return 0})}},Ta={name:"background-color",initialValue:"transparent",prefix:!1,type:3,format:"color"},We=function(e,A){var t=hA.parse(e,A[0]),r=A[1];return r&&O(r)?{color:t,stop:r}:{color:t,stop:null}},dB=function(e,A){var t=e[0],r=e[e.length-1];t.stop===null&&(t.stop=V),r.stop===null&&(r.stop=FA);for(var B=[],n=0,s=0;sn?B.push(a):B.push(n),n=a}else B.push(null)}for(var o=null,s=0;ss.optimumDistance)?{optimumCorner:i,optimumDistance:Q}:s},{optimumDistance:B?1/0:-1/0,optimumCorner:null}).optimumCorner},Ga=function(e,A,t,r,B){var n=0,s=0;switch(e.size){case 0:e.shape===0?n=s=Math.min(Math.abs(A),Math.abs(A-r),Math.abs(t),Math.abs(t-B)):e.shape===1&&(n=Math.min(Math.abs(A),Math.abs(A-r)),s=Math.min(Math.abs(t),Math.abs(t-B)));break;case 2:if(e.shape===0)n=s=Math.min(BA(A,t),BA(A,t-B),BA(A-r,t),BA(A-r,t-B));else if(e.shape===1){var i=Math.min(Math.abs(t),Math.abs(t-B))/Math.min(Math.abs(A),Math.abs(A-r)),a=EB(r,B,A,t,!0),o=a[0],Q=a[1];n=BA(o-A,(Q-t)/i),s=i*n}break;case 1:e.shape===0?n=s=Math.max(Math.abs(A),Math.abs(A-r),Math.abs(t),Math.abs(t-B)):e.shape===1&&(n=Math.max(Math.abs(A),Math.abs(A-r)),s=Math.max(Math.abs(t),Math.abs(t-B)));break;case 3:if(e.shape===0)n=s=Math.max(BA(A,t),BA(A,t-B),BA(A-r,t),BA(A-r,t-B));else if(e.shape===1){var i=Math.max(Math.abs(t),Math.abs(t-B))/Math.max(Math.abs(A),Math.abs(A-r)),g=EB(r,B,A,t,!1),o=g[0],Q=g[1];n=BA(o-A,(Q-t)/i),s=i*n}break}return Array.isArray(e.size)&&(n=D(e.size[0],r),s=e.size.length===2?D(e.size[1],B):n),[n,s]},Ra=function(e,A){var t=$(180),r=[];return sA(A).forEach(function(B,n){if(n===0){var s=B[0];if(s.type===20&&s.value==="to"){t=fB(B);return}else if(CB(s)){t=Ye.parse(e,s);return}}var i=We(e,B);r.push(i)}),{angle:t,stops:r,type:1}},Ze=function(e,A){var t=$(180),r=[];return sA(A).forEach(function(B,n){if(n===0){var s=B[0];if(s.type===20&&["top","left","right","bottom"].indexOf(s.value)!==-1){t=fB(B);return}else if(CB(s)){t=(Ye.parse(e,s)+$(270))%$(360);return}}var i=We(e,B);r.push(i)}),{angle:t,stops:r,type:1}},Va=function(e,A){var t=$(180),r=[],B=1,n=0,s=3,i=[];return sA(A).forEach(function(a,o){var Q=a[0];if(o===0){if(L(Q)&&Q.value==="linear"){B=1;return}else if(L(Q)&&Q.value==="radial"){B=2;return}}if(Q.type===18){if(Q.name==="from"){var g=hA.parse(e,Q.values[0]);r.push({stop:V,color:g})}else if(Q.name==="to"){var g=hA.parse(e,Q.values[0]);r.push({stop:FA,color:g})}else if(Q.name==="color-stop"){var c=Q.values.filter(_A);if(c.length===2){var g=hA.parse(e,c[1]),u=c[0];NA(u)&&r.push({stop:{type:16,number:u.number*100,flags:u.flags},color:g})}}}}),B===1?{angle:(t+$(180))%$(360),stops:r,type:B}:{size:s,shape:n,stops:r,position:i,type:B}},HB="closest-side",pB="farthest-side",IB="closest-corner",vB="farthest-corner",yB="circle",mB="ellipse",KB="cover",LB="contain",Na=function(e,A){var t=0,r=3,B=[],n=[];return sA(A).forEach(function(s,i){var a=!0;if(i===0){var o=!1;a=s.reduce(function(g,c){if(o)if(L(c))switch(c.value){case"center":return n.push(Pr),g;case"top":case"left":return n.push(V),g;case"right":case"bottom":return n.push(FA),g}else(O(c)||UA(c))&&n.push(c);else if(L(c))switch(c.value){case yB:return t=0,!1;case mB:return t=1,!1;case"at":return o=!0,!1;case HB:return r=0,!1;case KB:case pB:return r=1,!1;case LB:case IB:return r=2,!1;case vB:return r=3,!1}else if(UA(c)||O(c))return Array.isArray(r)||(r=[]),r.push(c),!1;return g},a)}if(a){var Q=We(e,s);B.push(Q)}}),{size:r,shape:t,stops:B,position:n,type:2}},qe=function(e,A){var t=0,r=3,B=[],n=[];return sA(A).forEach(function(s,i){var a=!0;if(i===0?a=s.reduce(function(Q,g){if(L(g))switch(g.value){case"center":return n.push(Pr),!1;case"top":case"left":return n.push(V),!1;case"right":case"bottom":return n.push(FA),!1}else if(O(g)||UA(g))return n.push(g),!1;return Q},a):i===1&&(a=s.reduce(function(Q,g){if(L(g))switch(g.value){case yB:return t=0,!1;case mB:return t=1,!1;case LB:case HB:return r=0,!1;case pB:return r=1,!1;case IB:return r=2,!1;case KB:case vB:return r=3,!1}else if(UA(g)||O(g))return Array.isArray(r)||(r=[]),r.push(g),!1;return Q},a)),a){var o=We(e,s);B.push(o)}}),{size:r,shape:t,stops:B,position:n,type:2}},_a=function(e){return e.type===1},Xa=function(e){return e.type===2},kr={name:"image",parse:function(e,A){if(A.type===22){var t={url:A.value,type:0};return e.cache.addImage(A.value),t}if(A.type===18){var r=bB[A.name];if(typeof r>"u")throw new Error('Attempting to parse an unsupported image function "'+A.name+'"');return r(e,A.values)}throw new Error("Unsupported image type "+A.type)}};function Pa(e){return!(e.type===20&&e.value==="none")&&(e.type!==18||!!bB[e.name])}var bB={"linear-gradient":Ra,"-moz-linear-gradient":Ze,"-ms-linear-gradient":Ze,"-o-linear-gradient":Ze,"-webkit-linear-gradient":Ze,"radial-gradient":Na,"-moz-radial-gradient":qe,"-ms-radial-gradient":qe,"-o-radial-gradient":qe,"-webkit-radial-gradient":qe,"-webkit-gradient":Va},Ja={name:"background-image",initialValue:"none",type:1,prefix:!1,parse:function(e,A){if(A.length===0)return[];var t=A[0];return t.type===20&&t.value==="none"?[]:A.filter(function(r){return _A(r)&&Pa(r)}).map(function(r){return kr.parse(e,r)})}},ka={name:"background-origin",initialValue:"border-box",prefix:!1,type:1,parse:function(e,A){return A.map(function(t){if(L(t))switch(t.value){case"padding-box":return 1;case"content-box":return 2}return 0})}},Ya={name:"background-position",initialValue:"0% 0%",type:1,prefix:!1,parse:function(e,A){return sA(A).map(function(t){return t.filter(O)}).map(gB)}},Wa={name:"background-repeat",initialValue:"repeat",prefix:!1,type:1,parse:function(e,A){return sA(A).map(function(t){return t.filter(L).map(function(r){return r.value}).join(" ")}).map(Za)}},Za=function(e){switch(e){case"no-repeat":return 1;case"repeat-x":case"repeat no-repeat":return 2;case"repeat-y":case"no-repeat repeat":return 3;case"repeat":default:return 0}},XA;(function(e){e.AUTO="auto",e.CONTAIN="contain",e.COVER="cover"})(XA||(XA={}));var qa={name:"background-size",initialValue:"0",prefix:!1,type:1,parse:function(e,A){return sA(A).map(function(t){return t.filter(ja)})}},ja=function(e){return L(e)||O(e)},je=function(e){return{name:"border-"+e+"-color",initialValue:"transparent",prefix:!1,type:3,format:"color"}},za=je("top"),$a=je("right"),Ai=je("bottom"),ei=je("left"),ze=function(e){return{name:"border-radius-"+e,initialValue:"0 0",prefix:!1,type:1,parse:function(A,t){return gB(t.filter(O))}}},ri=ze("top-left"),ti=ze("top-right"),Bi=ze("bottom-right"),ni=ze("bottom-left"),$e=function(e){return{name:"border-"+e+"-style",initialValue:"solid",prefix:!1,type:2,parse:function(A,t){switch(t){case"none":return 0;case"dashed":return 2;case"dotted":return 3;case"double":return 4}return 1}}},si=$e("top"),ai=$e("right"),ii=$e("bottom"),oi=$e("left"),Ar=function(e){return{name:"border-"+e+"-width",initialValue:"0",type:0,prefix:!1,parse:function(A,t){return we(t)?t.number:0}}},Qi=Ar("top"),gi=Ar("right"),ci=Ar("bottom"),wi=Ar("left"),li={name:"color",initialValue:"transparent",prefix:!1,type:3,format:"color"},ui={name:"direction",initialValue:"ltr",prefix:!1,type:2,parse:function(e,A){switch(A){case"rtl":return 1;case"ltr":default:return 0}}},Ci={name:"display",initialValue:"inline-block",prefix:!1,type:1,parse:function(e,A){return A.filter(L).reduce(function(t,r){return t|fi(r.value)},0)}},fi=function(e){switch(e){case"block":case"-webkit-box":return 2;case"inline":return 4;case"run-in":return 8;case"flow":return 16;case"flow-root":return 32;case"table":return 64;case"flex":case"-webkit-flex":return 128;case"grid":case"-ms-grid":return 256;case"ruby":return 512;case"subgrid":return 1024;case"list-item":return 2048;case"table-row-group":return 4096;case"table-header-group":return 8192;case"table-footer-group":return 16384;case"table-row":return 32768;case"table-cell":return 65536;case"table-column-group":return 131072;case"table-column":return 262144;case"table-caption":return 524288;case"ruby-base":return 1048576;case"ruby-text":return 2097152;case"ruby-base-container":return 4194304;case"ruby-text-container":return 8388608;case"contents":return 16777216;case"inline-block":return 33554432;case"inline-list-item":return 67108864;case"inline-table":return 134217728;case"inline-flex":return 268435456;case"inline-grid":return 536870912}return 0},Ui={name:"float",initialValue:"none",prefix:!1,type:2,parse:function(e,A){switch(A){case"left":return 1;case"right":return 2;case"inline-start":return 3;case"inline-end":return 4}return 0}},Fi={name:"letter-spacing",initialValue:"0",prefix:!1,type:0,parse:function(e,A){return A.type===20&&A.value==="normal"?0:A.type===17||A.type===15?A.number:0}},er;(function(e){e.NORMAL="normal",e.STRICT="strict"})(er||(er={}));var hi={name:"line-break",initialValue:"normal",prefix:!1,type:2,parse:function(e,A){switch(A){case"strict":return er.STRICT;case"normal":default:return er.NORMAL}}},di={name:"line-height",initialValue:"normal",prefix:!1,type:4},DB=function(e,A){return L(e)&&e.value==="normal"?1.2*A:e.type===17?A*e.number:O(e)?D(e,A):A},Ei={name:"list-style-image",initialValue:"none",type:0,prefix:!1,parse:function(e,A){return A.type===20&&A.value==="none"?null:kr.parse(e,A)}},Hi={name:"list-style-position",initialValue:"outside",prefix:!1,type:2,parse:function(e,A){switch(A){case"inside":return 0;case"outside":default:return 1}}},Yr={name:"list-style-type",initialValue:"none",prefix:!1,type:2,parse:function(e,A){switch(A){case"disc":return 0;case"circle":return 1;case"square":return 2;case"decimal":return 3;case"cjk-decimal":return 4;case"decimal-leading-zero":return 5;case"lower-roman":return 6;case"upper-roman":return 7;case"lower-greek":return 8;case"lower-alpha":return 9;case"upper-alpha":return 10;case"arabic-indic":return 11;case"armenian":return 12;case"bengali":return 13;case"cambodian":return 14;case"cjk-earthly-branch":return 15;case"cjk-heavenly-stem":return 16;case"cjk-ideographic":return 17;case"devanagari":return 18;case"ethiopic-numeric":return 19;case"georgian":return 20;case"gujarati":return 21;case"gurmukhi":return 22;case"hebrew":return 22;case"hiragana":return 23;case"hiragana-iroha":return 24;case"japanese-formal":return 25;case"japanese-informal":return 26;case"kannada":return 27;case"katakana":return 28;case"katakana-iroha":return 29;case"khmer":return 30;case"korean-hangul-formal":return 31;case"korean-hanja-formal":return 32;case"korean-hanja-informal":return 33;case"lao":return 34;case"lower-armenian":return 35;case"malayalam":return 36;case"mongolian":return 37;case"myanmar":return 38;case"oriya":return 39;case"persian":return 40;case"simp-chinese-formal":return 41;case"simp-chinese-informal":return 42;case"tamil":return 43;case"telugu":return 44;case"thai":return 45;case"tibetan":return 46;case"trad-chinese-formal":return 47;case"trad-chinese-informal":return 48;case"upper-armenian":return 49;case"disclosure-open":return 50;case"disclosure-closed":return 51;case"none":default:return-1}}},rr=function(e){return{name:"margin-"+e,initialValue:"0",prefix:!1,type:4}},pi=rr("top"),Ii=rr("right"),vi=rr("bottom"),yi=rr("left"),mi={name:"overflow",initialValue:"visible",prefix:!1,type:1,parse:function(e,A){return A.filter(L).map(function(t){switch(t.value){case"hidden":return 1;case"scroll":return 2;case"clip":return 3;case"auto":return 4;case"visible":default:return 0}})}},Ki={name:"overflow-wrap",initialValue:"normal",prefix:!1,type:2,parse:function(e,A){switch(A){case"break-word":return"break-word";case"normal":default:return"normal"}}},tr=function(e){return{name:"padding-"+e,initialValue:"0",prefix:!1,type:3,format:"length-percentage"}},Li=tr("top"),bi=tr("right"),Di=tr("bottom"),xi=tr("left"),Si={name:"text-align",initialValue:"left",prefix:!1,type:2,parse:function(e,A){switch(A){case"right":return 2;case"center":case"justify":return 1;case"left":default:return 0}}},Ti={name:"position",initialValue:"static",prefix:!1,type:2,parse:function(e,A){switch(A){case"relative":return 1;case"absolute":return 2;case"fixed":return 3;case"sticky":return 4}return 0}},Oi={name:"text-shadow",initialValue:"none",type:1,prefix:!1,parse:function(e,A){return A.length===1&&Xr(A[0],"none")?[]:sA(A).map(function(t){for(var r={color:gA.TRANSPARENT,offsetX:V,offsetY:V,blur:V},B=0,n=0;n"u")throw new Error('Attempting to parse an unsupported transform function "'+A.name+'"');return t(A.values)}return null}},Ri=function(e){var A=e.filter(function(t){return t.type===17}).map(function(t){return t.number});return A.length===6?A:null},Vi=function(e){var A=e.filter(function(a){return a.type===17}).map(function(a){return a.number}),t=A[0],r=A[1];A[2],A[3];var B=A[4],n=A[5];A[6],A[7],A[8],A[9],A[10],A[11];var s=A[12],i=A[13];return A[14],A[15],A.length===16?[t,r,B,n,s,i]:null},Ni={matrix:Ri,matrix3d:Vi},xB={type:16,number:50,flags:ie},_i=[xB,xB],Xi={name:"transform-origin",initialValue:"50% 50%",prefix:!0,type:1,parse:function(e,A){var t=A.filter(O);return t.length!==2?_i:[t[0],t[1]]}},Pi={name:"visible",initialValue:"none",prefix:!1,type:2,parse:function(e,A){switch(A){case"hidden":return 1;case"collapse":return 2;case"visible":default:return 0}}},Ce;(function(e){e.NORMAL="normal",e.BREAK_ALL="break-all",e.KEEP_ALL="keep-all"})(Ce||(Ce={}));for(var Ji={name:"word-break",initialValue:"normal",prefix:!1,type:2,parse:function(e,A){switch(A){case"break-all":return Ce.BREAK_ALL;case"keep-all":return Ce.KEEP_ALL;case"normal":default:return Ce.NORMAL}}},ki={name:"z-index",initialValue:"auto",prefix:!1,type:0,parse:function(e,A){if(A.type===20)return{auto:!0,order:0};if(NA(A))return{auto:!1,order:A.number};throw new Error("Invalid z-index number parsed")}},SB={name:"time",parse:function(e,A){if(A.type===15)switch(A.unit.toLowerCase()){case"s":return 1e3*A.number;case"ms":return A.number}throw new Error("Unsupported time type")}},Yi={name:"opacity",initialValue:"1",type:0,prefix:!1,parse:function(e,A){return NA(A)?A.number:1}},Wi={name:"text-decoration-color",initialValue:"transparent",prefix:!1,type:3,format:"color"},Zi={name:"text-decoration-line",initialValue:"none",prefix:!1,type:1,parse:function(e,A){return A.filter(L).map(function(t){switch(t.value){case"underline":return 1;case"overline":return 2;case"line-through":return 3;case"none":return 4}return 0}).filter(function(t){return t!==0})}},qi={name:"font-family",initialValue:"",prefix:!1,type:1,parse:function(e,A){var t=[],r=[];return A.forEach(function(B){switch(B.type){case 20:case 0:t.push(B.value);break;case 17:t.push(B.number.toString());break;case 4:r.push(t.join(" ")),t.length=0;break}}),t.length&&r.push(t.join(" ")),r.map(function(B){return B.indexOf(" ")===-1?B:"'"+B+"'"})}},ji={name:"font-size",initialValue:"0",prefix:!1,type:3,format:"length"},zi={name:"font-weight",initialValue:"normal",type:0,prefix:!1,parse:function(e,A){if(NA(A))return A.number;if(L(A))switch(A.value){case"bold":return 700;case"normal":default:return 400}return 400}},$i={name:"font-variant",initialValue:"none",type:1,prefix:!1,parse:function(e,A){return A.filter(L).map(function(t){return t.value})}},Ao={name:"font-style",initialValue:"normal",prefix:!1,type:2,parse:function(e,A){switch(A){case"oblique":return"oblique";case"italic":return"italic";case"normal":default:return"normal"}}},G=function(e,A){return(e&A)!==0},eo={name:"content",initialValue:"none",type:1,prefix:!1,parse:function(e,A){if(A.length===0)return[];var t=A[0];return t.type===20&&t.value==="none"?[]:A}},ro={name:"counter-increment",initialValue:"none",prefix:!0,type:1,parse:function(e,A){if(A.length===0)return null;var t=A[0];if(t.type===20&&t.value==="none")return null;for(var r=[],B=A.filter(QB),n=0;n1?1:0],this.overflowWrap=U(A,Ki,t.overflowWrap),this.paddingTop=U(A,Li,t.paddingTop),this.paddingRight=U(A,bi,t.paddingRight),this.paddingBottom=U(A,Di,t.paddingBottom),this.paddingLeft=U(A,xi,t.paddingLeft),this.paintOrder=U(A,ao,t.paintOrder),this.position=U(A,Ti,t.position),this.textAlign=U(A,Si,t.textAlign),this.textDecorationColor=U(A,Wi,(r=t.textDecorationColor)!==null&&r!==void 0?r:t.color),this.textDecorationLine=U(A,Zi,(B=t.textDecorationLine)!==null&&B!==void 0?B:t.textDecoration),this.textShadow=U(A,Oi,t.textShadow),this.textTransform=U(A,Mi,t.textTransform),this.transform=U(A,Gi,t.transform),this.transformOrigin=U(A,Xi,t.transformOrigin),this.visibility=U(A,Pi,t.visibility),this.webkitTextStrokeColor=U(A,io,t.webkitTextStrokeColor),this.webkitTextStrokeWidth=U(A,oo,t.webkitTextStrokeWidth),this.wordBreak=U(A,Ji,t.wordBreak),this.zIndex=U(A,ki,t.zIndex)}return e.prototype.isVisible=function(){return this.display>0&&this.opacity>0&&this.visibility===0},e.prototype.isTransparent=function(){return dA(this.backgroundColor)},e.prototype.isTransformed=function(){return this.transform!==null},e.prototype.isPositioned=function(){return this.position!==0},e.prototype.isPositionedWithZIndex=function(){return this.isPositioned()&&!this.zIndex.auto},e.prototype.isFloating=function(){return this.float!==0},e.prototype.isInlineLevel=function(){return G(this.display,4)||G(this.display,33554432)||G(this.display,268435456)||G(this.display,536870912)||G(this.display,67108864)||G(this.display,134217728)},e})(),go=(function(){function e(A,t){this.content=U(A,eo,t.content),this.quotes=U(A,no,t.quotes)}return e})(),OB=(function(){function e(A,t){this.counterIncrement=U(A,ro,t.counterIncrement),this.counterReset=U(A,to,t.counterReset)}return e})(),U=function(e,A,t){var r=new iB,B=t!==null&&typeof t<"u"?t.toString():A.initialValue;r.write(B);var n=new oB(r.read());switch(A.type){case 2:var s=n.parseComponentValue();return A.parse(e,L(s)?s.value:A.initialValue);case 0:return A.parse(e,n.parseComponentValue());case 1:return A.parse(e,n.parseComponentValues());case 4:return n.parseComponentValue();case 3:switch(A.format){case"angle":return Ye.parse(e,n.parseComponentValue());case"color":return hA.parse(e,n.parseComponentValue());case"image":return kr.parse(e,n.parseComponentValue());case"length":var i=n.parseComponentValue();return UA(i)?i:V;case"length-percentage":var a=n.parseComponentValue();return O(a)?a:V;case"time":return SB.parse(e,n.parseComponentValue())}break}},co="data-html2canvas-debug",wo=function(e){var A=e.getAttribute(co);switch(A){case"all":return 1;case"clone":return 2;case"parse":return 3;case"render":return 4;default:return 0}},Wr=function(e,A){var t=wo(e);return t===1||A===t},aA=(function(){function e(A,t){if(this.context=A,this.textNodes=[],this.elements=[],this.flags=0,Wr(t,3))debugger;this.styles=new Qo(A,window.getComputedStyle(t,null)),it(t)&&(this.styles.animationDuration.some(function(r){return r>0})&&(t.style.animationDuration="0s"),this.styles.transform!==null&&(t.style.transform="none")),this.bounds=ye(this.context,t),Wr(t,4)&&(this.flags|=16)}return e})(),lo="AAAAAAAAAAAAEA4AGBkAAFAaAAACAAAAAAAIABAAGAAwADgACAAQAAgAEAAIABAACAAQAAgAEAAIABAACAAQAAgAEAAIABAAQABIAEQATAAIABAACAAQAAgAEAAIABAAVABcAAgAEAAIABAACAAQAGAAaABwAHgAgACIAI4AlgAIABAAmwCjAKgAsAC2AL4AvQDFAMoA0gBPAVYBWgEIAAgACACMANoAYgFkAWwBdAF8AX0BhQGNAZUBlgGeAaMBlQGWAasBswF8AbsBwwF0AcsBYwHTAQgA2wG/AOMBdAF8AekB8QF0AfkB+wHiAHQBfAEIAAMC5gQIAAsCEgIIAAgAFgIeAggAIgIpAggAMQI5AkACygEIAAgASAJQAlgCYAIIAAgACAAKBQoFCgUTBRMFGQUrBSsFCAAIAAgACAAIAAgACAAIAAgACABdAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABoAmgCrwGvAQgAbgJ2AggAHgEIAAgACADnAXsCCAAIAAgAgwIIAAgACAAIAAgACACKAggAkQKZAggAPADJAAgAoQKkAqwCsgK6AsICCADJAggA0AIIAAgACAAIANYC3gIIAAgACAAIAAgACABAAOYCCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAkASoB+QIEAAgACAA8AEMCCABCBQgACABJBVAFCAAIAAgACAAIAAgACAAIAAgACABTBVoFCAAIAFoFCABfBWUFCAAIAAgACAAIAAgAbQUIAAgACAAIAAgACABzBXsFfQWFBYoFigWKBZEFigWKBYoFmAWfBaYFrgWxBbkFCAAIAAgACAAIAAgACAAIAAgACAAIAMEFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAMgFCADQBQgACAAIAAgACAAIAAgACAAIAAgACAAIAO4CCAAIAAgAiQAIAAgACABAAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAD0AggACAD8AggACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIANYFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAMDvwAIAAgAJAIIAAgACAAIAAgACAAIAAgACwMTAwgACAB9BOsEGwMjAwgAKwMyAwsFYgE3A/MEPwMIAEUDTQNRAwgAWQOsAGEDCAAIAAgACAAIAAgACABpAzQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFOgU0BTUFNgU3BTgFOQU6BTQFNQU2BTcFOAU5BToFNAU1BTYFNwU4BTkFIQUoBSwFCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABtAwgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABMAEwACAAIAAgACAAIABgACAAIAAgACAC/AAgACAAyAQgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACACAAIAAwAAgACAAIAAgACAAIAAgACAAIAAAARABIAAgACAAIABQASAAIAAgAIABwAEAAjgCIABsAqAC2AL0AigDQAtwC+IJIQqVAZUBWQqVAZUBlQGVAZUBlQGrC5UBlQGVAZUBlQGVAZUBlQGVAXsKlQGVAbAK6wsrDGUMpQzlDJUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAZUBlQGVAfAKAAuZA64AtwCJALoC6ADwAAgAuACgA/oEpgO6AqsD+AAIAAgAswMIAAgACAAIAIkAuwP5AfsBwwPLAwgACAAIAAgACADRA9kDCAAIAOED6QMIAAgACAAIAAgACADuA/YDCAAIAP4DyQAIAAgABgQIAAgAXQAOBAgACAAIAAgACAAIABMECAAIAAgACAAIAAgACAD8AAQBCAAIAAgAGgQiBCoECAExBAgAEAEIAAgACAAIAAgACAAIAAgACAAIAAgACAA4BAgACABABEYECAAIAAgATAQYAQgAVAQIAAgACAAIAAgACAAIAAgACAAIAFoECAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAOQEIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAB+BAcACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAEABhgSMBAgACAAIAAgAlAQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAwAEAAQABAADAAMAAwADAAQABAAEAAQABAAEAAQABHATAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAdQMIAAgACAAIAAgACAAIAMkACAAIAAgAfQMIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACACFA4kDCAAIAAgACAAIAOcBCAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAIcDCAAIAAgACAAIAAgACAAIAAgACAAIAJEDCAAIAAgACADFAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABgBAgAZgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAbAQCBXIECAAIAHkECAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACABAAJwEQACjBKoEsgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAC6BMIECAAIAAgACAAIAAgACABmBAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAxwQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAGYECAAIAAgAzgQIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgAigWKBYoFigWKBYoFigWKBd0FXwUIAOIF6gXxBYoF3gT5BQAGCAaKBYoFigWKBYoFigWKBYoFigWKBYoFigXWBIoFigWKBYoFigWKBYoFigWKBYsFEAaKBYoFigWKBYoFigWKBRQGCACKBYoFigWKBQgACAAIANEECAAIABgGigUgBggAJgYIAC4GMwaKBYoF0wQ3Bj4GigWKBYoFigWKBYoFigWKBYoFigWKBYoFigUIAAgACAAIAAgACAAIAAgAigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWKBYoFigWLBf///////wQABAAEAAQABAAEAAQABAAEAAQAAwAEAAQAAgAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAQADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAUAAAAFAAUAAAAFAAUAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUAAQAAAAUABQAFAAUABQAFAAAAAAAFAAUAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAFAAUAAQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUABQAFAAAABwAHAAcAAAAHAAcABwAFAAEAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAcABwAFAAUAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAQABAAAAAAAAAAAAAAAFAAUABQAFAAAABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABwAHAAcAAAAHAAcAAAAAAAUABQAHAAUAAQAHAAEABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABwABAAUABQAFAAUAAAAAAAAAAAAAAAEAAQABAAEAAQABAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABQANAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAQABAAEAAQABAAEAAQABAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAABQAHAAUABQAFAAAAAAAAAAcABQAFAAUABQAFAAQABAAEAAQABAAEAAQABAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUAAAAFAAUABQAFAAUAAAAFAAUABQAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAAAAAAAAAAAAUABQAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAUAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABwAHAAcABwAFAAcABwAAAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAUABwAHAAUABQAFAAUAAAAAAAcABwAAAAAABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAABQAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAABwAHAAcABQAFAAAAAAAAAAAABQAFAAAAAAAFAAUABQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAFAAUABQAFAAUAAAAFAAUABwAAAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAFAAUABwAFAAUABQAFAAAAAAAHAAcAAAAAAAcABwAFAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABwAAAAAAAAAHAAcABwAAAAcABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAABQAHAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAcABwAAAAUABQAFAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABQAHAAcABQAHAAcAAAAFAAcABwAAAAcABwAFAAUAAAAAAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAFAAcABwAFAAUABQAAAAUAAAAHAAcABwAHAAcABwAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAHAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAABwAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAUAAAAFAAAAAAAAAAAABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABwAFAAUABQAFAAUAAAAFAAUAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABwAFAAUABQAFAAUABQAAAAUABQAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABQAFAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABQAFAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAHAAUABQAFAAUABQAFAAUABwAHAAcABwAHAAcABwAHAAUABwAHAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABwAHAAcABwAFAAUABwAHAAcAAAAAAAAAAAAHAAcABQAHAAcABwAHAAcABwAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAcABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAHAAUABQAFAAUABQAFAAUAAAAFAAAABQAAAAAABQAFAAUABQAFAAUABQAFAAcABwAHAAcABwAHAAUABQAFAAUABQAFAAUABQAFAAUAAAAAAAUABQAFAAUABQAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABwAFAAcABwAHAAcABwAFAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAUABQAFAAUABwAHAAUABQAHAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABQAFAAcABwAHAAUABwAFAAUABQAHAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAUABQAFAAUABQAFAAUABQAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAcABQAFAAUABQAFAAUABQAAAAAAAAAAAAUAAAAAAAAAAAAAAAAABQAAAAAABwAFAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUAAAAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAABQAAAAAAAAAFAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAUABQAHAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAHAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAUABQAFAAUABQAHAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAcABwAFAAUABQAFAAcABwAFAAUABwAHAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAFAAcABwAFAAUABwAHAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAFAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAFAAUABQAAAAAABQAFAAAAAAAAAAAAAAAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAFAAcABwAAAAAAAAAAAAAABwAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAFAAcABwAFAAcABwAAAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAFAAUABQAAAAUABQAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABwAFAAUABQAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABQAFAAUABQAFAAUABQAFAAUABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAHAAcABQAHAAUABQAAAAAAAAAAAAAAAAAFAAAABwAHAAcABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAHAAcABwAAAAAABwAHAAAAAAAHAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABwAHAAUABQAFAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABQAFAAUABQAFAAUABwAFAAcABwAFAAcABQAFAAcABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAHAAcABQAFAAUABQAAAAAABwAHAAcABwAFAAUABwAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAHAAUABQAFAAUABQAFAAUABQAHAAcABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABwAFAAcABwAFAAUABQAFAAUABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAcABwAFAAUABQAFAAcABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAUABQAFAAUABQAHAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAFAAUABQAFAAAAAAAFAAUABwAHAAcABwAFAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABwAHAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAcABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUAAAAHAAUABQAFAAUABQAFAAUABwAFAAUABwAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUAAAAAAAAABQAAAAUABQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAcABwAHAAcAAAAFAAUAAAAHAAcABQAHAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAAAAAAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAAAAUABQAFAAAAAAAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAAAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAFAAUABQAAAAAABQAFAAUABQAFAAUABQAAAAUABQAAAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAUABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAFAAUABQAFAAUABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAFAAUABQAFAAUADgAOAA4ADgAOAA4ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAA8ADwAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAcABwAHAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAAAAAAAAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAMAAwADAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAAAAAAAAAAAAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAKAAoACgAAAAAAAAAAAAsADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwACwAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAMAAwADAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAADgAOAA4AAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAAAA4ADgAOAA4ADgAOAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAA4AAAAOAAAAAAAAAAAAAAAAAA4AAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAADgAAAAAAAAAAAA4AAAAOAAAAAAAAAAAADgAOAA4AAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAA4ADgAOAA4ADgAOAA4ADgAOAAAADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4ADgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4ADgAOAA4AAAAAAAAAAAAAAAAAAAAAAA4ADgAOAA4ADgAOAA4ADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAOAA4ADgAOAA4ADgAAAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4ADgAOAA4AAAAAAAAAAAA=",MB="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",fe=typeof Uint8Array>"u"?[]:new Uint8Array(256),Br=0;Br>4,Q[B++]=(s&15)<<4|i>>2,Q[B++]=(i&3)<<6|a&63;return o},Co=function(e){for(var A=e.length,t=[],r=0;r>DA,Fo=1<>DA,Eo=GB+ho,Ho=Eo,po=32,Io=Ho+po,vo=65536>>Zr,yo=1<=0){if(A<55296||A>56319&&A<=65535)return t=this.index[A>>DA],t=(t<>DA)],t=(t<>Zr),t=this.index[t],t+=A>>DA&mo,t=this.index[t],t=(t<"u"?[]:new Uint8Array(256),nr=0;nr=55296&&B<=56319&&t>10)+55296,s%1024+56320)),(B+1===t||r.length>16384)&&(n+=String.fromCharCode.apply(String,r),r.length=0)}return n},Mo=Lo(lo),AA="×",tt="÷",Go=function(e){return Mo.get(e)},Ro=function(e,A,t){var r=t-2,B=A[r],n=A[t-1],s=A[t];if(n===zr&&s===$r)return AA;if(n===zr||n===$r||n===NB||s===zr||s===$r||s===NB)return tt;if(n===XB&&[XB,At,PB,JB].indexOf(s)!==-1||(n===PB||n===At)&&(s===At||s===et)||(n===JB||n===et)&&s===et||s===kB||s===_B||s===So||n===xo)return AA;if(n===kB&&s===YB){for(;B===_B;)B=A[--r];if(B===YB)return AA}if(n===rt&&s===rt){for(var i=0;B===rt;)i++,B=A[--r];if(i%2===0)return AA}return tt},Vo=function(e){var A=To(e),t=A.length,r=0,B=0,n=A.map(Go);return{next:function(){if(r>=t)return{done:!0,value:null};for(var s=AA;rs.x||Q.y>s.y;return s=Q,o===0?!0:g});return e.body.removeChild(A),i},Po=function(){return typeof new Image().crossOrigin<"u"},Jo=function(){return typeof new XMLHttpRequest().responseType=="string"},ko=function(e){var A=new Image,t=e.createElement("canvas"),r=t.getContext("2d");if(!r)return!1;A.src="data:image/svg+xml,";try{r.drawImage(A,0,0),t.toDataURL()}catch{return!1}return!0},WB=function(e){return e[0]===0&&e[1]===255&&e[2]===0&&e[3]===255},Yo=function(e){var A=e.createElement("canvas"),t=100;A.width=t,A.height=t;var r=A.getContext("2d");if(!r)return Promise.reject(!1);r.fillStyle="rgb(0, 255, 0)",r.fillRect(0,0,t,t);var B=new Image,n=A.toDataURL();B.src=n;var s=Bt(t,t,0,0,B);return r.fillStyle="red",r.fillRect(0,0,t,t),ZB(s).then(function(i){r.drawImage(i,0,0);var a=r.getImageData(0,0,t,t).data;r.fillStyle="red",r.fillRect(0,0,t,t);var o=e.createElement("div");return o.style.backgroundImage="url("+n+")",o.style.height=t+"px",WB(a)?ZB(Bt(t,t,0,0,o)):Promise.reject(!1)}).then(function(i){return r.drawImage(i,0,0),WB(r.getImageData(0,0,t,t).data)}).catch(function(){return!1})},Bt=function(e,A,t,r,B){var n="http://www.w3.org/2000/svg",s=document.createElementNS(n,"svg"),i=document.createElementNS(n,"foreignObject");return s.setAttributeNS(null,"width",e.toString()),s.setAttributeNS(null,"height",A.toString()),i.setAttributeNS(null,"width","100%"),i.setAttributeNS(null,"height","100%"),i.setAttributeNS(null,"x",t.toString()),i.setAttributeNS(null,"y",r.toString()),i.setAttributeNS(null,"externalResourcesRequired","true"),s.appendChild(i),i.appendChild(B),s},ZB=function(e){return new Promise(function(A,t){var r=new Image;r.onload=function(){return A(r)},r.onerror=t,r.src="data:image/svg+xml;charset=utf-8,"+encodeURIComponent(new XMLSerializer().serializeToString(e))})},N={get SUPPORT_RANGE_BOUNDS(){var e=_o(document);return Object.defineProperty(N,"SUPPORT_RANGE_BOUNDS",{value:e}),e},get SUPPORT_WORD_BREAKING(){var e=N.SUPPORT_RANGE_BOUNDS&&Xo(document);return Object.defineProperty(N,"SUPPORT_WORD_BREAKING",{value:e}),e},get SUPPORT_SVG_DRAWING(){var e=ko(document);return Object.defineProperty(N,"SUPPORT_SVG_DRAWING",{value:e}),e},get SUPPORT_FOREIGNOBJECT_DRAWING(){var e=typeof Array.from=="function"&&typeof window.fetch=="function"?Yo(document):Promise.resolve(!1);return Object.defineProperty(N,"SUPPORT_FOREIGNOBJECT_DRAWING",{value:e}),e},get SUPPORT_CORS_IMAGES(){var e=Po();return Object.defineProperty(N,"SUPPORT_CORS_IMAGES",{value:e}),e},get SUPPORT_RESPONSE_TYPE(){var e=Jo();return Object.defineProperty(N,"SUPPORT_RESPONSE_TYPE",{value:e}),e},get SUPPORT_CORS_XHR(){var e="withCredentials"in new XMLHttpRequest;return Object.defineProperty(N,"SUPPORT_CORS_XHR",{value:e}),e},get SUPPORT_NATIVE_TEXT_SEGMENTATION(){var e=!!(typeof Intl<"u"&&Intl.Segmenter);return Object.defineProperty(N,"SUPPORT_NATIVE_TEXT_SEGMENTATION",{value:e}),e}},Ue=(function(){function e(A,t){this.text=A,this.bounds=t}return e})(),Wo=function(e,A,t,r){var B=jo(A,t),n=[],s=0;return B.forEach(function(i){if(t.textDecorationLine.length||i.trim().length>0)if(N.SUPPORT_RANGE_BOUNDS){var a=qB(r,s,i.length).getClientRects();if(a.length>1){var o=nt(i),Q=0;o.forEach(function(c){n.push(new Ue(c,oA.fromDOMRectList(e,qB(r,Q+s,c.length).getClientRects()))),Q+=c.length})}else n.push(new Ue(i,oA.fromDOMRectList(e,a)))}else{var g=r.splitText(i.length);n.push(new Ue(i,Zo(e,r))),r=g}else N.SUPPORT_RANGE_BOUNDS||(r=r.splitText(i.length));s+=i.length}),n},Zo=function(e,A){var t=A.ownerDocument;if(t){var r=t.createElement("html2canvaswrapper");r.appendChild(A.cloneNode(!0));var B=A.parentNode;if(B){B.replaceChild(r,A);var n=ye(e,r);return r.firstChild&&B.replaceChild(r.firstChild,r),n}}return oA.EMPTY},qB=function(e,A,t){var r=e.ownerDocument;if(!r)throw new Error("Node has no owner document");var B=r.createRange();return B.setStart(e,A),B.setEnd(e,A+t),B},nt=function(e){if(N.SUPPORT_NATIVE_TEXT_SEGMENTATION){var A=new Intl.Segmenter(void 0,{granularity:"grapheme"});return Array.from(A.segment(e)).map(function(t){return t.segment})}return No(e)},qo=function(e,A){if(N.SUPPORT_NATIVE_TEXT_SEGMENTATION){var t=new Intl.Segmenter(void 0,{granularity:"word"});return Array.from(t.segment(e)).map(function(r){return r.segment})}return $o(e,A)},jo=function(e,A){return A.letterSpacing!==0?nt(e):qo(e,A)},zo=[32,160,4961,65792,65793,4153,4241],$o=function(e,A){for(var t=Is(e,{lineBreak:A.lineBreak,wordBreak:A.overflowWrap==="break-word"?"break-word":A.wordBreak}),r=[],B,n=function(){if(B.value){var s=B.value.slice(),i=me(s),a="";i.forEach(function(o){zo.indexOf(o)===-1?a+=S(o):(a.length&&r.push(a),r.push(S(o)),a="")}),a.length&&r.push(a)}};!(B=t.next()).done;)n();return r},AQ=(function(){function e(A,t,r){this.text=eQ(t.data,r.textTransform),this.textBounds=Wo(A,this.text,r,t)}return e})(),eQ=function(e,A){switch(A){case 1:return e.toLowerCase();case 3:return e.replace(rQ,tQ);case 2:return e.toUpperCase();default:return e}},rQ=/(^|\s|:|-|\(|\))([a-z])/g,tQ=function(e,A,t){return e.length>0?A+t.toUpperCase():e},jB=(function(e){tA(A,e);function A(t,r){var B=e.call(this,t,r)||this;return B.src=r.currentSrc||r.src,B.intrinsicWidth=r.naturalWidth,B.intrinsicHeight=r.naturalHeight,B.context.cache.addImage(B.src),B}return A})(aA),zB=(function(e){tA(A,e);function A(t,r){var B=e.call(this,t,r)||this;return B.canvas=r,B.intrinsicWidth=r.width,B.intrinsicHeight=r.height,B}return A})(aA),$B=(function(e){tA(A,e);function A(t,r){var B=e.call(this,t,r)||this,n=new XMLSerializer,s=ye(t,r);return r.setAttribute("width",s.width+"px"),r.setAttribute("height",s.height+"px"),B.svg="data:image/svg+xml,"+encodeURIComponent(n.serializeToString(r)),B.intrinsicWidth=r.width.baseVal.value,B.intrinsicHeight=r.height.baseVal.value,B.context.cache.addImage(B.svg),B}return A})(aA),An=(function(e){tA(A,e);function A(t,r){var B=e.call(this,t,r)||this;return B.value=r.value,B}return A})(aA),st=(function(e){tA(A,e);function A(t,r){var B=e.call(this,t,r)||this;return B.start=r.start,B.reversed=typeof r.reversed=="boolean"&&r.reversed===!0,B}return A})(aA),BQ=[{type:15,flags:0,unit:"px",number:3}],nQ=[{type:16,flags:0,number:50}],sQ=function(e){return e.width>e.height?new oA(e.left+(e.width-e.height)/2,e.top,e.height,e.height):e.width0)t.textNodes.push(new AQ(e,B,t.styles));else if(PA(B))if(ln(B)&&B.assignedNodes)B.assignedNodes().forEach(function(i){return ir(e,i,t,r)});else{var s=nn(e,B);s.styles.isVisible()&&(QQ(B,s,r)?s.flags|=4:gQ(s.styles)&&(s.flags|=2),oQ.indexOf(B.tagName)!==-1&&(s.flags|=8),t.elements.push(s),B.slot,B.shadowRoot?ir(e,B.shadowRoot,s,r):!Qr(B)&&!on(B)&&!gr(B)&&ir(e,B,s,r))}},nn=function(e,A){return Qt(A)?new jB(e,A):Qn(A)?new zB(e,A):on(A)?new $B(e,A):cQ(A)?new An(e,A):wQ(A)?new st(e,A):lQ(A)?new at(e,A):gr(A)?new rn(e,A):Qr(A)?new tn(e,A):cn(A)?new Bn(e,A):new aA(e,A)},sn=function(e,A){var t=nn(e,A);return t.flags|=4,ir(e,A,t,t),t},QQ=function(e,A,t){return A.styles.isPositionedWithZIndex()||A.styles.opacity<1||A.styles.isTransformed()||ot(e)&&t.styles.isTransparent()},gQ=function(e){return e.isPositioned()||e.isFloating()},an=function(e){return e.nodeType===Node.TEXT_NODE},PA=function(e){return e.nodeType===Node.ELEMENT_NODE},it=function(e){return PA(e)&&typeof e.style<"u"&&!or(e)},or=function(e){return typeof e.className=="object"},cQ=function(e){return e.tagName==="LI"},wQ=function(e){return e.tagName==="OL"},lQ=function(e){return e.tagName==="INPUT"},uQ=function(e){return e.tagName==="HTML"},on=function(e){return e.tagName==="svg"},ot=function(e){return e.tagName==="BODY"},Qn=function(e){return e.tagName==="CANVAS"},gn=function(e){return e.tagName==="VIDEO"},Qt=function(e){return e.tagName==="IMG"},cn=function(e){return e.tagName==="IFRAME"},wn=function(e){return e.tagName==="STYLE"},CQ=function(e){return e.tagName==="SCRIPT"},Qr=function(e){return e.tagName==="TEXTAREA"},gr=function(e){return e.tagName==="SELECT"},ln=function(e){return e.tagName==="SLOT"},un=function(e){return e.tagName.indexOf("-")>0},fQ=(function(){function e(){this.counters={}}return e.prototype.getCounterValue=function(A){var t=this.counters[A];return t&&t.length?t[t.length-1]:1},e.prototype.getCounterValues=function(A){var t=this.counters[A];return t||[]},e.prototype.pop=function(A){var t=this;A.forEach(function(r){return t.counters[r].pop()})},e.prototype.parse=function(A){var t=this,r=A.counterIncrement,B=A.counterReset,n=!0;r!==null&&r.forEach(function(i){var a=t.counters[i.counter];a&&i.increment!==0&&(n=!1,a.length||a.push(1),a[Math.max(0,a.length-1)]+=i.increment)});var s=[];return n&&B.forEach(function(i){var a=t.counters[i.counter];s.push(i.counter),a||(a=t.counters[i.counter]=[]),a.push(i.reset)}),s},e})(),Cn={integers:[1e3,900,500,400,100,90,50,40,10,9,5,4,1],values:["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"]},fn={integers:[9e3,8e3,7e3,6e3,5e3,4e3,3e3,2e3,1e3,900,800,700,600,500,400,300,200,100,90,80,70,60,50,40,30,20,10,9,8,7,6,5,4,3,2,1],values:["Ք","Փ","Ւ","Ց","Ր","Տ","Վ","Ս","Ռ","Ջ","Պ","Չ","Ո","Շ","Ն","Յ","Մ","Ճ","Ղ","Ձ","Հ","Կ","Ծ","Խ","Լ","Ի","Ժ","Թ","Ը","Է","Զ","Ե","Դ","Գ","Բ","Ա"]},UQ={integers:[1e4,9e3,8e3,7e3,6e3,5e3,4e3,3e3,2e3,1e3,400,300,200,100,90,80,70,60,50,40,30,20,19,18,17,16,15,10,9,8,7,6,5,4,3,2,1],values:["י׳","ט׳","ח׳","ז׳","ו׳","ה׳","ד׳","ג׳","ב׳","א׳","ת","ש","ר","ק","צ","פ","ע","ס","נ","מ","ל","כ","יט","יח","יז","טז","טו","י","ט","ח","ז","ו","ה","ד","ג","ב","א"]},FQ={integers:[1e4,9e3,8e3,7e3,6e3,5e3,4e3,3e3,2e3,1e3,900,800,700,600,500,400,300,200,100,90,80,70,60,50,40,30,20,10,9,8,7,6,5,4,3,2,1],values:["ჵ","ჰ","ჯ","ჴ","ხ","ჭ","წ","ძ","ც","ჩ","შ","ყ","ღ","ქ","ფ","ჳ","ტ","ს","რ","ჟ","პ","ო","ჲ","ნ","მ","ლ","კ","ი","თ","ჱ","ზ","ვ","ე","დ","გ","ბ","ა"]},JA=function(e,A,t,r,B,n){return et?he(e,B,n.length>0):r.integers.reduce(function(s,i,a){for(;e>=i;)e-=i,s+=r.values[a];return s},"")+n},Un=function(e,A,t,r){var B="";do t||e--,B=r(e)+B,e/=A;while(e*A>=A);return B},T=function(e,A,t,r,B){var n=t-A+1;return(e<0?"-":"")+(Un(Math.abs(e),n,r,function(s){return S(Math.floor(s%n)+A)})+B)},xA=function(e,A,t){t===void 0&&(t=". ");var r=A.length;return Un(Math.abs(e),r,!1,function(B){return A[Math.floor(B%r)]})+t},kA=1,HA=2,pA=4,Fe=8,cA=function(e,A,t,r,B,n){if(e<-9999||e>9999)return he(e,4,B.length>0);var s=Math.abs(e),i=B;if(s===0)return A[0]+i;for(var a=0;s>0&&a<=4;a++){var o=s%10;o===0&&G(n,kA)&&i!==""?i=A[o]+i:o>1||o===1&&a===0||o===1&&a===1&&G(n,HA)||o===1&&a===1&&G(n,pA)&&e>100||o===1&&a>1&&G(n,Fe)?i=A[o]+(a>0?t[a-1]:"")+i:o===1&&a>0&&(i=t[a-1]+i),s=Math.floor(s/10)}return(e<0?r:"")+i},Fn="十百千萬",hn="拾佰仟萬",dn="マイナス",gt="마이너스",he=function(e,A,t){var r=t?". ":"",B=t?"、":"",n=t?", ":"",s=t?" ":"";switch(A){case 0:return"•"+s;case 1:return"◦"+s;case 2:return"◾"+s;case 5:var i=T(e,48,57,!0,r);return i.length<4?"0"+i:i;case 4:return xA(e,"〇一二三四五六七八九",B);case 6:return JA(e,1,3999,Cn,3,r).toLowerCase();case 7:return JA(e,1,3999,Cn,3,r);case 8:return T(e,945,969,!1,r);case 9:return T(e,97,122,!1,r);case 10:return T(e,65,90,!1,r);case 11:return T(e,1632,1641,!0,r);case 12:case 49:return JA(e,1,9999,fn,3,r);case 35:return JA(e,1,9999,fn,3,r).toLowerCase();case 13:return T(e,2534,2543,!0,r);case 14:case 30:return T(e,6112,6121,!0,r);case 15:return xA(e,"子丑寅卯辰巳午未申酉戌亥",B);case 16:return xA(e,"甲乙丙丁戊己庚辛壬癸",B);case 17:case 48:return cA(e,"零一二三四五六七八九",Fn,"負",B,HA|pA|Fe);case 47:return cA(e,"零壹貳參肆伍陸柒捌玖",hn,"負",B,kA|HA|pA|Fe);case 42:return cA(e,"零一二三四五六七八九",Fn,"负",B,HA|pA|Fe);case 41:return cA(e,"零壹贰叁肆伍陆柒捌玖",hn,"负",B,kA|HA|pA|Fe);case 26:return cA(e,"〇一二三四五六七八九","十百千万",dn,B,0);case 25:return cA(e,"零壱弐参四伍六七八九","拾百千万",dn,B,kA|HA|pA);case 31:return cA(e,"영일이삼사오육칠팔구","십백천만",gt,n,kA|HA|pA);case 33:return cA(e,"零一二三四五六七八九","十百千萬",gt,n,0);case 32:return cA(e,"零壹貳參四五六七八九","拾百千",gt,n,kA|HA|pA);case 18:return T(e,2406,2415,!0,r);case 20:return JA(e,1,19999,FQ,3,r);case 21:return T(e,2790,2799,!0,r);case 22:return T(e,2662,2671,!0,r);case 22:return JA(e,1,10999,UQ,3,r);case 23:return xA(e,"あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわゐゑをん");case 24:return xA(e,"いろはにほへとちりぬるをわかよたれそつねならむうゐのおくやまけふこえてあさきゆめみしゑひもせす");case 27:return T(e,3302,3311,!0,r);case 28:return xA(e,"アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヰヱヲン",B);case 29:return xA(e,"イロハニホヘトチリヌルヲワカヨタレソツネナラムウヰノオクヤマケフコエテアサキユメミシヱヒモセス",B);case 34:return T(e,3792,3801,!0,r);case 37:return T(e,6160,6169,!0,r);case 38:return T(e,4160,4169,!0,r);case 39:return T(e,2918,2927,!0,r);case 40:return T(e,1776,1785,!0,r);case 43:return T(e,3046,3055,!0,r);case 44:return T(e,3174,3183,!0,r);case 45:return T(e,3664,3673,!0,r);case 46:return T(e,3872,3881,!0,r);case 3:default:return T(e,48,57,!0,r)}},En="data-html2canvas-ignore",Hn=(function(){function e(A,t,r){if(this.context=A,this.options=r,this.scrolledElements=[],this.referenceElement=t,this.counters=new fQ,this.quoteDepth=0,!t.ownerDocument)throw new Error("Cloned element does not have an owner document");this.documentElement=this.cloneNode(t.ownerDocument.documentElement,!1)}return e.prototype.toIFrame=function(A,t){var r=this,B=hQ(A,t);if(!B.contentWindow)return Promise.reject("Unable to find iframe window");var n=A.defaultView.pageXOffset,s=A.defaultView.pageYOffset,i=B.contentWindow,a=i.document,o=HQ(B).then(function(){return J(r,void 0,void 0,function(){var Q,g;return X(this,function(c){switch(c.label){case 0:return this.scrolledElements.forEach(yQ),i&&(i.scrollTo(t.left,t.top),/(iPad|iPhone|iPod)/g.test(navigator.userAgent)&&(i.scrollY!==t.top||i.scrollX!==t.left)&&(this.context.logger.warn("Unable to restore scroll position for cloned document"),this.context.windowBounds=this.context.windowBounds.add(i.scrollX-t.left,i.scrollY-t.top,0,0))),Q=this.options.onclone,g=this.clonedReferenceElement,typeof g>"u"?[2,Promise.reject("Error finding the "+this.referenceElement.nodeName+" in the cloned document")]:a.fonts&&a.fonts.ready?[4,a.fonts.ready]:[3,2];case 1:c.sent(),c.label=2;case 2:return/(AppleWebKit)/g.test(navigator.userAgent)?[4,EQ(a)]:[3,4];case 3:c.sent(),c.label=4;case 4:return typeof Q=="function"?[2,Promise.resolve().then(function(){return Q(a,g)}).then(function(){return B})]:[2,B]}})})});return a.open(),a.write(IQ(document.doctype)+""),vQ(this.referenceElement.ownerDocument,n,s),a.replaceChild(a.adoptNode(this.documentElement),a.documentElement),a.close(),o},e.prototype.createElementClone=function(A){if(Wr(A,2))debugger;if(Qn(A))return this.createCanvasClone(A);if(gn(A))return this.createVideoClone(A);if(wn(A))return this.createStyleClone(A);var t=A.cloneNode(!1);return Qt(t)&&(Qt(A)&&A.currentSrc&&A.currentSrc!==A.src&&(t.src=A.currentSrc,t.srcset=""),t.loading==="lazy"&&(t.loading="eager")),un(t)?this.createCustomElementClone(t):t},e.prototype.createCustomElementClone=function(A){var t=document.createElement("html2canvascustomelement");return ct(A.style,t),t},e.prototype.createStyleClone=function(A){try{var t=A.sheet;if(t&&t.cssRules){var r=[].slice.call(t.cssRules,0).reduce(function(n,s){return s&&typeof s.cssText=="string"?n+s.cssText:n},""),B=A.cloneNode(!1);return B.textContent=r,B}}catch(n){if(this.context.logger.error("Unable to access cssRules property",n),n.name!=="SecurityError")throw n}return A.cloneNode(!1)},e.prototype.createCanvasClone=function(A){var t;if(this.options.inlineImages&&A.ownerDocument){var r=A.ownerDocument.createElement("img");try{return r.src=A.toDataURL(),r}catch{this.context.logger.info("Unable to inline canvas contents, canvas is tainted",A)}}var B=A.cloneNode(!1);try{B.width=A.width,B.height=A.height;var n=A.getContext("2d"),s=B.getContext("2d");if(s)if(!this.options.allowTaint&&n)s.putImageData(n.getImageData(0,0,A.width,A.height),0,0);else{var i=(t=A.getContext("webgl2"))!==null&&t!==void 0?t:A.getContext("webgl");if(i){var a=i.getContextAttributes();(a==null?void 0:a.preserveDrawingBuffer)===!1&&this.context.logger.warn("Unable to clone WebGL context as it has preserveDrawingBuffer=false",A)}s.drawImage(A,0,0)}return B}catch{this.context.logger.info("Unable to clone canvas as it is tainted",A)}return B},e.prototype.createVideoClone=function(A){var t=A.ownerDocument.createElement("canvas");t.width=A.offsetWidth,t.height=A.offsetHeight;var r=t.getContext("2d");try{return r&&(r.drawImage(A,0,0,t.width,t.height),this.options.allowTaint||r.getImageData(0,0,t.width,t.height)),t}catch{this.context.logger.info("Unable to clone video as it is tainted",A)}var B=A.ownerDocument.createElement("canvas");return B.width=A.offsetWidth,B.height=A.offsetHeight,B},e.prototype.appendChildNode=function(A,t,r){(!PA(t)||!CQ(t)&&!t.hasAttribute(En)&&(typeof this.options.ignoreElements!="function"||!this.options.ignoreElements(t)))&&(!this.options.copyStyles||!PA(t)||!wn(t))&&A.appendChild(this.cloneNode(t,r))},e.prototype.cloneChildNodes=function(A,t,r){for(var B=this,n=A.shadowRoot?A.shadowRoot.firstChild:A.firstChild;n;n=n.nextSibling)if(PA(n)&&ln(n)&&typeof n.assignedNodes=="function"){var s=n.assignedNodes();s.length&&s.forEach(function(i){return B.appendChildNode(t,i,r)})}else this.appendChildNode(t,n,r)},e.prototype.cloneNode=function(A,t){if(an(A))return document.createTextNode(A.data);if(!A.ownerDocument)return A.cloneNode(!1);var r=A.ownerDocument.defaultView;if(r&&PA(A)&&(it(A)||or(A))){var B=this.createElementClone(A);B.style.transitionProperty="none";var n=r.getComputedStyle(A),s=r.getComputedStyle(A,":before"),i=r.getComputedStyle(A,":after");this.referenceElement===A&&it(B)&&(this.clonedReferenceElement=B),ot(B)&&LQ(B);var a=this.counters.parse(new OB(this.context,n)),o=this.resolvePseudoContent(A,B,s,de.BEFORE);un(A)&&(t=!0),gn(A)||this.cloneChildNodes(A,B,t),o&&B.insertBefore(o,B.firstChild);var Q=this.resolvePseudoContent(A,B,i,de.AFTER);return Q&&B.appendChild(Q),this.counters.pop(a),(n&&(this.options.copyStyles||or(A))&&!cn(A)||t)&&ct(n,B),(A.scrollTop!==0||A.scrollLeft!==0)&&this.scrolledElements.push([B,A.scrollLeft,A.scrollTop]),(Qr(A)||gr(A))&&(Qr(B)||gr(B))&&(B.value=A.value),B}return A.cloneNode(!1)},e.prototype.resolvePseudoContent=function(A,t,r,B){var n=this;if(r){var s=r.content,i=t.ownerDocument;if(!(!i||!s||s==="none"||s==="-moz-alt-content"||r.display==="none")){this.counters.parse(new OB(this.context,r));var a=new go(this.context,r),o=i.createElement("html2canvaspseudoelement");ct(r,o),a.content.forEach(function(g){if(g.type===0)o.appendChild(i.createTextNode(g.value));else if(g.type===22){var c=i.createElement("img");c.src=g.value,c.style.opacity="1",o.appendChild(c)}else if(g.type===18){if(g.name==="attr"){var u=g.values.filter(L);u.length&&o.appendChild(i.createTextNode(A.getAttribute(u[0].value)||""))}else if(g.name==="counter"){var w=g.values.filter(_A),l=w[0],H=w[1];if(l&&L(l)){var F=n.counters.getCounterValue(l.value),h=H&&L(H)?Yr.parse(n.context,H.value):3;o.appendChild(i.createTextNode(he(F,h,!1)))}}else if(g.name==="counters"){var m=g.values.filter(_A),l=m[0],p=m[1],H=m[2];if(l&&L(l)){var d=n.counters.getCounterValues(l.value),f=H&&L(H)?Yr.parse(n.context,H.value):3,v=p&&p.type===0?p.value:"",y=d.map(function(Y){return he(Y,f,!1)}).join(v);o.appendChild(i.createTextNode(y))}}}else if(g.type===20)switch(g.value){case"open-quote":o.appendChild(i.createTextNode(TB(a.quotes,n.quoteDepth++,!0)));break;case"close-quote":o.appendChild(i.createTextNode(TB(a.quotes,--n.quoteDepth,!1)));break;default:o.appendChild(i.createTextNode(g.value))}}),o.className=wt+" "+lt;var Q=B===de.BEFORE?" "+wt:" "+lt;return or(t)?t.className.baseValue+=Q:t.className+=Q,o}}},e.destroy=function(A){return A.parentNode?(A.parentNode.removeChild(A),!0):!1},e})(),de;(function(e){e[e.BEFORE=0]="BEFORE",e[e.AFTER=1]="AFTER"})(de||(de={}));var hQ=function(e,A){var t=e.createElement("iframe");return t.className="html2canvas-container",t.style.visibility="hidden",t.style.position="fixed",t.style.left="-10000px",t.style.top="0px",t.style.border="0",t.width=A.width.toString(),t.height=A.height.toString(),t.scrolling="no",t.setAttribute(En,"true"),e.body.appendChild(t),t},dQ=function(e){return new Promise(function(A){if(e.complete){A();return}if(!e.src){A();return}e.onload=A,e.onerror=A})},EQ=function(e){return Promise.all([].slice.call(e.images,0).map(dQ))},HQ=function(e){return new Promise(function(A,t){var r=e.contentWindow;if(!r)return t("No window assigned for iframe");var B=r.document;r.onload=e.onload=function(){r.onload=e.onload=null;var n=setInterval(function(){B.body.childNodes.length>0&&B.readyState==="complete"&&(clearInterval(n),A(e))},50)}})},pQ=["all","d","content"],ct=function(e,A){for(var t=e.length-1;t>=0;t--){var r=e.item(t);pQ.indexOf(r)===-1&&A.style.setProperty(r,e.getPropertyValue(r))}return A},IQ=function(e){var A="";return e&&(A+=""),A},vQ=function(e,A,t){e&&e.defaultView&&(A!==e.defaultView.pageXOffset||t!==e.defaultView.pageYOffset)&&e.defaultView.scrollTo(A,t)},yQ=function(e){var A=e[0],t=e[1],r=e[2];A.scrollLeft=t,A.scrollTop=r},mQ=":before",KQ=":after",wt="___html2canvas___pseudoelement_before",lt="___html2canvas___pseudoelement_after",pn=`{ + content: "" !important; + display: none !important; +}`,LQ=function(e){bQ(e,"."+wt+mQ+pn+` + .`+lt+KQ+pn)},bQ=function(e,A){var t=e.ownerDocument;if(t){var r=t.createElement("style");r.textContent=A,e.appendChild(r)}},In=(function(){function e(){}return e.getOrigin=function(A){var t=e._link;return t?(t.href=A,t.href=t.href,t.protocol+t.hostname+t.port):"about:blank"},e.isSameOrigin=function(A){return e.getOrigin(A)===e._origin},e.setContext=function(A){e._link=A.document.createElement("a"),e._origin=e.getOrigin(A.location.href)},e._origin="about:blank",e})(),DQ=(function(){function e(A,t){this.context=A,this._options=t,this._cache={}}return e.prototype.addImage=function(A){var t=Promise.resolve();return this.has(A)||(Ct(A)||OQ(A))&&(this._cache[A]=this.loadImage(A)).catch(function(){}),t},e.prototype.match=function(A){return this._cache[A]},e.prototype.loadImage=function(A){return J(this,void 0,void 0,function(){var t,r,B,n,s=this;return X(this,function(i){switch(i.label){case 0:return t=In.isSameOrigin(A),r=!ut(A)&&this._options.useCORS===!0&&N.SUPPORT_CORS_IMAGES&&!t,B=!ut(A)&&!t&&!Ct(A)&&typeof this._options.proxy=="string"&&N.SUPPORT_CORS_XHR&&!r,!t&&this._options.allowTaint===!1&&!ut(A)&&!Ct(A)&&!B&&!r?[2]:(n=A,B?[4,this.proxy(n)]:[3,2]);case 1:n=i.sent(),i.label=2;case 2:return this.context.logger.debug("Added image "+A.substring(0,256)),[4,new Promise(function(a,o){var Q=new Image;Q.onload=function(){return a(Q)},Q.onerror=o,(MQ(n)||r)&&(Q.crossOrigin="anonymous"),Q.src=n,Q.complete===!0&&setTimeout(function(){return a(Q)},500),s._options.imageTimeout>0&&setTimeout(function(){return o("Timed out ("+s._options.imageTimeout+"ms) loading image")},s._options.imageTimeout)})];case 3:return[2,i.sent()]}})})},e.prototype.has=function(A){return typeof this._cache[A]<"u"},e.prototype.keys=function(){return Promise.resolve(Object.keys(this._cache))},e.prototype.proxy=function(A){var t=this,r=this._options.proxy;if(!r)throw new Error("No proxy defined");var B=A.substring(0,256);return new Promise(function(n,s){var i=N.SUPPORT_RESPONSE_TYPE?"blob":"text",a=new XMLHttpRequest;a.onload=function(){if(a.status===200)if(i==="text")n(a.response);else{var g=new FileReader;g.addEventListener("load",function(){return n(g.result)},!1),g.addEventListener("error",function(c){return s(c)},!1),g.readAsDataURL(a.response)}else s("Failed to proxy resource "+B+" with status code "+a.status)},a.onerror=s;var o=r.indexOf("?")>-1?"&":"?";if(a.open("GET",""+r+o+"url="+encodeURIComponent(A)+"&responseType="+i),i!=="text"&&a instanceof XMLHttpRequest&&(a.responseType=i),t._options.imageTimeout){var Q=t._options.imageTimeout;a.timeout=Q,a.ontimeout=function(){return s("Timed out ("+Q+"ms) proxying "+B)}}a.send()})},e})(),xQ=/^data:image\/svg\+xml/i,SQ=/^data:image\/.*;base64,/i,TQ=/^data:image\/.*/i,OQ=function(e){return N.SUPPORT_SVG_DRAWING||!GQ(e)},ut=function(e){return TQ.test(e)},MQ=function(e){return SQ.test(e)},Ct=function(e){return e.substr(0,4)==="blob"},GQ=function(e){return e.substr(-3).toLowerCase()==="svg"||xQ.test(e)},C=(function(){function e(A,t){this.type=0,this.x=A,this.y=t}return e.prototype.add=function(A,t){return new e(this.x+A,this.y+t)},e})(),YA=function(e,A,t){return new C(e.x+(A.x-e.x)*t,e.y+(A.y-e.y)*t)},cr=(function(){function e(A,t,r,B){this.type=1,this.start=A,this.startControl=t,this.endControl=r,this.end=B}return e.prototype.subdivide=function(A,t){var r=YA(this.start,this.startControl,A),B=YA(this.startControl,this.endControl,A),n=YA(this.endControl,this.end,A),s=YA(r,B,A),i=YA(B,n,A),a=YA(s,i,A);return t?new e(this.start,r,s,a):new e(a,i,n,this.end)},e.prototype.add=function(A,t){return new e(this.start.add(A,t),this.startControl.add(A,t),this.endControl.add(A,t),this.end.add(A,t))},e.prototype.reverse=function(){return new e(this.end,this.endControl,this.startControl,this.start)},e})(),eA=function(e){return e.type===1},RQ=(function(){function e(A){var t=A.styles,r=A.bounds,B=le(t.borderTopLeftRadius,r.width,r.height),n=B[0],s=B[1],i=le(t.borderTopRightRadius,r.width,r.height),a=i[0],o=i[1],Q=le(t.borderBottomRightRadius,r.width,r.height),g=Q[0],c=Q[1],u=le(t.borderBottomLeftRadius,r.width,r.height),w=u[0],l=u[1],H=[];H.push((n+a)/r.width),H.push((w+g)/r.width),H.push((s+l)/r.height),H.push((o+c)/r.height);var F=Math.max.apply(Math,H);F>1&&(n/=F,s/=F,a/=F,o/=F,g/=F,c/=F,w/=F,l/=F);var h=r.width-a,m=r.height-c,p=r.width-g,d=r.height-l,f=t.borderTopWidth,v=t.borderRightWidth,y=t.borderBottomWidth,E=t.borderLeftWidth,M=D(t.paddingTop,A.bounds.width),Y=D(t.paddingRight,A.bounds.width),j=D(t.paddingBottom,A.bounds.width),b=D(t.paddingLeft,A.bounds.width);this.topLeftBorderDoubleOuterBox=n>0||s>0?x(r.left+E/3,r.top+f/3,n-E/3,s-f/3,K.TOP_LEFT):new C(r.left+E/3,r.top+f/3),this.topRightBorderDoubleOuterBox=n>0||s>0?x(r.left+h,r.top+f/3,a-v/3,o-f/3,K.TOP_RIGHT):new C(r.left+r.width-v/3,r.top+f/3),this.bottomRightBorderDoubleOuterBox=g>0||c>0?x(r.left+p,r.top+m,g-v/3,c-y/3,K.BOTTOM_RIGHT):new C(r.left+r.width-v/3,r.top+r.height-y/3),this.bottomLeftBorderDoubleOuterBox=w>0||l>0?x(r.left+E/3,r.top+d,w-E/3,l-y/3,K.BOTTOM_LEFT):new C(r.left+E/3,r.top+r.height-y/3),this.topLeftBorderDoubleInnerBox=n>0||s>0?x(r.left+E*2/3,r.top+f*2/3,n-E*2/3,s-f*2/3,K.TOP_LEFT):new C(r.left+E*2/3,r.top+f*2/3),this.topRightBorderDoubleInnerBox=n>0||s>0?x(r.left+h,r.top+f*2/3,a-v*2/3,o-f*2/3,K.TOP_RIGHT):new C(r.left+r.width-v*2/3,r.top+f*2/3),this.bottomRightBorderDoubleInnerBox=g>0||c>0?x(r.left+p,r.top+m,g-v*2/3,c-y*2/3,K.BOTTOM_RIGHT):new C(r.left+r.width-v*2/3,r.top+r.height-y*2/3),this.bottomLeftBorderDoubleInnerBox=w>0||l>0?x(r.left+E*2/3,r.top+d,w-E*2/3,l-y*2/3,K.BOTTOM_LEFT):new C(r.left+E*2/3,r.top+r.height-y*2/3),this.topLeftBorderStroke=n>0||s>0?x(r.left+E/2,r.top+f/2,n-E/2,s-f/2,K.TOP_LEFT):new C(r.left+E/2,r.top+f/2),this.topRightBorderStroke=n>0||s>0?x(r.left+h,r.top+f/2,a-v/2,o-f/2,K.TOP_RIGHT):new C(r.left+r.width-v/2,r.top+f/2),this.bottomRightBorderStroke=g>0||c>0?x(r.left+p,r.top+m,g-v/2,c-y/2,K.BOTTOM_RIGHT):new C(r.left+r.width-v/2,r.top+r.height-y/2),this.bottomLeftBorderStroke=w>0||l>0?x(r.left+E/2,r.top+d,w-E/2,l-y/2,K.BOTTOM_LEFT):new C(r.left+E/2,r.top+r.height-y/2),this.topLeftBorderBox=n>0||s>0?x(r.left,r.top,n,s,K.TOP_LEFT):new C(r.left,r.top),this.topRightBorderBox=a>0||o>0?x(r.left+h,r.top,a,o,K.TOP_RIGHT):new C(r.left+r.width,r.top),this.bottomRightBorderBox=g>0||c>0?x(r.left+p,r.top+m,g,c,K.BOTTOM_RIGHT):new C(r.left+r.width,r.top+r.height),this.bottomLeftBorderBox=w>0||l>0?x(r.left,r.top+d,w,l,K.BOTTOM_LEFT):new C(r.left,r.top+r.height),this.topLeftPaddingBox=n>0||s>0?x(r.left+E,r.top+f,Math.max(0,n-E),Math.max(0,s-f),K.TOP_LEFT):new C(r.left+E,r.top+f),this.topRightPaddingBox=a>0||o>0?x(r.left+Math.min(h,r.width-v),r.top+f,h>r.width+v?0:Math.max(0,a-v),Math.max(0,o-f),K.TOP_RIGHT):new C(r.left+r.width-v,r.top+f),this.bottomRightPaddingBox=g>0||c>0?x(r.left+Math.min(p,r.width-E),r.top+Math.min(m,r.height-y),Math.max(0,g-v),Math.max(0,c-y),K.BOTTOM_RIGHT):new C(r.left+r.width-v,r.top+r.height-y),this.bottomLeftPaddingBox=w>0||l>0?x(r.left+E,r.top+Math.min(d,r.height-y),Math.max(0,w-E),Math.max(0,l-y),K.BOTTOM_LEFT):new C(r.left+E,r.top+r.height-y),this.topLeftContentBox=n>0||s>0?x(r.left+E+b,r.top+f+M,Math.max(0,n-(E+b)),Math.max(0,s-(f+M)),K.TOP_LEFT):new C(r.left+E+b,r.top+f+M),this.topRightContentBox=a>0||o>0?x(r.left+Math.min(h,r.width+E+b),r.top+f+M,h>r.width+E+b?0:a-E+b,o-(f+M),K.TOP_RIGHT):new C(r.left+r.width-(v+Y),r.top+f+M),this.bottomRightContentBox=g>0||c>0?x(r.left+Math.min(p,r.width-(E+b)),r.top+Math.min(m,r.height+f+M),Math.max(0,g-(v+Y)),c-(y+j),K.BOTTOM_RIGHT):new C(r.left+r.width-(v+Y),r.top+r.height-(y+j)),this.bottomLeftContentBox=w>0||l>0?x(r.left+E+b,r.top+d,Math.max(0,w-(E+b)),l-(y+j),K.BOTTOM_LEFT):new C(r.left+E+b,r.top+r.height-(y+j))}return e})(),K;(function(e){e[e.TOP_LEFT=0]="TOP_LEFT",e[e.TOP_RIGHT=1]="TOP_RIGHT",e[e.BOTTOM_RIGHT=2]="BOTTOM_RIGHT",e[e.BOTTOM_LEFT=3]="BOTTOM_LEFT"})(K||(K={}));var x=function(e,A,t,r,B){var n=4*((Math.sqrt(2)-1)/3),s=t*n,i=r*n,a=e+t,o=A+r;switch(B){case K.TOP_LEFT:return new cr(new C(e,o),new C(e,o-i),new C(a-s,A),new C(a,A));case K.TOP_RIGHT:return new cr(new C(e,A),new C(e+s,A),new C(a,o-i),new C(a,o));case K.BOTTOM_RIGHT:return new cr(new C(a,A),new C(a,A+i),new C(e+s,o),new C(e,o));case K.BOTTOM_LEFT:default:return new cr(new C(a,o),new C(a-s,o),new C(e,A+i),new C(e,A))}},wr=function(e){return[e.topLeftBorderBox,e.topRightBorderBox,e.bottomRightBorderBox,e.bottomLeftBorderBox]},VQ=function(e){return[e.topLeftContentBox,e.topRightContentBox,e.bottomRightContentBox,e.bottomLeftContentBox]},lr=function(e){return[e.topLeftPaddingBox,e.topRightPaddingBox,e.bottomRightPaddingBox,e.bottomLeftPaddingBox]},NQ=(function(){function e(A,t,r){this.offsetX=A,this.offsetY=t,this.matrix=r,this.type=0,this.target=6}return e})(),ur=(function(){function e(A,t){this.path=A,this.target=t,this.type=1}return e})(),_Q=(function(){function e(A){this.opacity=A,this.type=2,this.target=6}return e})(),XQ=function(e){return e.type===0},vn=function(e){return e.type===1},PQ=function(e){return e.type===2},yn=function(e,A){return e.length===A.length?e.some(function(t,r){return t===A[r]}):!1},JQ=function(e,A,t,r,B){return e.map(function(n,s){switch(s){case 0:return n.add(A,t);case 1:return n.add(A+r,t);case 2:return n.add(A+r,t+B);case 3:return n.add(A,t+B)}return n})},mn=(function(){function e(A){this.element=A,this.inlineLevel=[],this.nonInlineLevel=[],this.negativeZIndex=[],this.zeroOrAutoZIndexOrTransformedOrOpacity=[],this.positiveZIndex=[],this.nonPositionedFloats=[],this.nonPositionedInlineLevel=[]}return e})(),Kn=(function(){function e(A,t){if(this.container=A,this.parent=t,this.effects=[],this.curves=new RQ(this.container),this.container.styles.opacity<1&&this.effects.push(new _Q(this.container.styles.opacity)),this.container.styles.transform!==null){var r=this.container.bounds.left+this.container.styles.transformOrigin[0].number,B=this.container.bounds.top+this.container.styles.transformOrigin[1].number,n=this.container.styles.transform;this.effects.push(new NQ(r,B,n))}if(this.container.styles.overflowX!==0){var s=wr(this.curves),i=lr(this.curves);yn(s,i)?this.effects.push(new ur(s,6)):(this.effects.push(new ur(s,2)),this.effects.push(new ur(i,4)))}}return e.prototype.getEffects=function(A){for(var t=[2,3].indexOf(this.container.styles.position)===-1,r=this.parent,B=this.effects.slice(0);r;){var n=r.effects.filter(function(a){return!vn(a)});if(t||r.container.styles.position!==0||!r.parent){if(B.unshift.apply(B,n),t=[2,3].indexOf(r.container.styles.position)===-1,r.container.styles.overflowX!==0){var s=wr(r.curves),i=lr(r.curves);yn(s,i)||B.unshift(new ur(i,6))}}else B.unshift.apply(B,n);r=r.parent}return B.filter(function(a){return G(a.target,A)})},e})(),ft=function(e,A,t,r){e.container.elements.forEach(function(B){var n=G(B.flags,4),s=G(B.flags,2),i=new Kn(B,e);G(B.styles.display,2048)&&r.push(i);var a=G(B.flags,8)?[]:r;if(n||s){var o=n||B.styles.isPositioned()?t:A,Q=new mn(i);if(B.styles.isPositioned()||B.styles.opacity<1||B.styles.isTransformed()){var g=B.styles.zIndex.order;if(g<0){var c=0;o.negativeZIndex.some(function(w,l){return g>w.element.container.styles.zIndex.order?(c=l,!1):c>0}),o.negativeZIndex.splice(c,0,Q)}else if(g>0){var u=0;o.positiveZIndex.some(function(w,l){return g>=w.element.container.styles.zIndex.order?(u=l+1,!1):u>0}),o.positiveZIndex.splice(u,0,Q)}else o.zeroOrAutoZIndexOrTransformedOrOpacity.push(Q)}else B.styles.isFloating()?o.nonPositionedFloats.push(Q):o.nonPositionedInlineLevel.push(Q);ft(i,Q,n?Q:t,a)}else B.styles.isInlineLevel()?A.inlineLevel.push(i):A.nonInlineLevel.push(i),ft(i,A,t,a);G(B.flags,8)&&Ln(B,a)})},Ln=function(e,A){for(var t=e instanceof st?e.start:1,r=e instanceof st?e.reversed:!1,B=0;B"u"?e[0]:t},$Q=function(e,A,t,r,B){var n=A[0],s=A[1],i=t[0],a=t[1];switch(e){case 2:return[new C(Math.round(r.left),Math.round(r.top+s)),new C(Math.round(r.left+r.width),Math.round(r.top+s)),new C(Math.round(r.left+r.width),Math.round(a+r.top+s)),new C(Math.round(r.left),Math.round(a+r.top+s))];case 3:return[new C(Math.round(r.left+n),Math.round(r.top)),new C(Math.round(r.left+n+i),Math.round(r.top)),new C(Math.round(r.left+n+i),Math.round(r.height+r.top)),new C(Math.round(r.left+n),Math.round(r.height+r.top))];case 1:return[new C(Math.round(r.left+n),Math.round(r.top+s)),new C(Math.round(r.left+n+i),Math.round(r.top+s)),new C(Math.round(r.left+n+i),Math.round(r.top+s+a)),new C(Math.round(r.left+n),Math.round(r.top+s+a))];default:return[new C(Math.round(B.left),Math.round(B.top)),new C(Math.round(B.left+B.width),Math.round(B.top)),new C(Math.round(B.left+B.width),Math.round(B.height+B.top)),new C(Math.round(B.left),Math.round(B.height+B.top))]}},Ag="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",xn="Hidden Text",eg=(function(){function e(A){this._data={},this._document=A}return e.prototype.parseMetrics=function(A,t){var r=this._document.createElement("div"),B=this._document.createElement("img"),n=this._document.createElement("span"),s=this._document.body;r.style.visibility="hidden",r.style.fontFamily=A,r.style.fontSize=t,r.style.margin="0",r.style.padding="0",r.style.whiteSpace="nowrap",s.appendChild(r),B.src=Ag,B.width=1,B.height=1,B.style.margin="0",B.style.padding="0",B.style.verticalAlign="baseline",n.style.fontFamily=A,n.style.fontSize=t,n.style.margin="0",n.style.padding="0",n.appendChild(this._document.createTextNode(xn)),r.appendChild(n),r.appendChild(B);var i=B.offsetTop-n.offsetTop+2;r.removeChild(n),r.appendChild(this._document.createTextNode(xn)),r.style.lineHeight="normal",B.style.verticalAlign="super";var a=B.offsetTop-r.offsetTop+2;return s.removeChild(r),{baseline:i,middle:a}},e.prototype.getMetrics=function(A,t){var r=A+" "+t;return typeof this._data[r]>"u"&&(this._data[r]=this.parseMetrics(A,t)),this._data[r]},e})(),Sn=(function(){function e(A,t){this.context=A,this.options=t}return e})(),rg=1e4,tg=(function(e){tA(A,e);function A(t,r){var B=e.call(this,t,r)||this;return B._activeEffects=[],B.canvas=r.canvas?r.canvas:document.createElement("canvas"),B.ctx=B.canvas.getContext("2d"),r.canvas||(B.canvas.width=Math.floor(r.width*r.scale),B.canvas.height=Math.floor(r.height*r.scale),B.canvas.style.width=r.width+"px",B.canvas.style.height=r.height+"px"),B.fontMetrics=new eg(document),B.ctx.scale(B.options.scale,B.options.scale),B.ctx.translate(-r.x,-r.y),B.ctx.textBaseline="bottom",B._activeEffects=[],B.context.logger.debug("Canvas renderer initialized ("+r.width+"x"+r.height+") with scale "+r.scale),B}return A.prototype.applyEffects=function(t){for(var r=this;this._activeEffects.length;)this.popEffect();t.forEach(function(B){return r.applyEffect(B)})},A.prototype.applyEffect=function(t){this.ctx.save(),PQ(t)&&(this.ctx.globalAlpha=t.opacity),XQ(t)&&(this.ctx.translate(t.offsetX,t.offsetY),this.ctx.transform(t.matrix[0],t.matrix[1],t.matrix[2],t.matrix[3],t.matrix[4],t.matrix[5]),this.ctx.translate(-t.offsetX,-t.offsetY)),vn(t)&&(this.path(t.path),this.ctx.clip()),this._activeEffects.push(t)},A.prototype.popEffect=function(){this._activeEffects.pop(),this.ctx.restore()},A.prototype.renderStack=function(t){return J(this,void 0,void 0,function(){var r;return X(this,function(B){switch(B.label){case 0:return r=t.element.container.styles,r.isVisible()?[4,this.renderStackContent(t)]:[3,2];case 1:B.sent(),B.label=2;case 2:return[2]}})})},A.prototype.renderNode=function(t){return J(this,void 0,void 0,function(){return X(this,function(r){switch(r.label){case 0:if(G(t.container.flags,16))debugger;return t.container.styles.isVisible()?[4,this.renderNodeBackgroundAndBorders(t)]:[3,3];case 1:return r.sent(),[4,this.renderNodeContent(t)];case 2:r.sent(),r.label=3;case 3:return[2]}})})},A.prototype.renderTextWithLetterSpacing=function(t,r,B){var n=this;if(r===0)this.ctx.fillText(t.text,t.bounds.left,t.bounds.top+B);else{var s=nt(t.text);s.reduce(function(i,a){return n.ctx.fillText(a,i,t.bounds.top+B),i+n.ctx.measureText(a).width},t.bounds.left)}},A.prototype.createFontStyle=function(t){var r=t.fontVariant.filter(function(s){return s==="normal"||s==="small-caps"}).join(""),B=ig(t.fontFamily).join(", "),n=we(t.fontSize)?""+t.fontSize.number+t.fontSize.unit:t.fontSize.number+"px";return[[t.fontStyle,r,t.fontWeight,n,B].join(" "),B,n]},A.prototype.renderTextNode=function(t,r){return J(this,void 0,void 0,function(){var B,n,s,i,a,o,Q,g,c=this;return X(this,function(u){return B=this.createFontStyle(r),n=B[0],s=B[1],i=B[2],this.ctx.font=n,this.ctx.direction=r.direction===1?"rtl":"ltr",this.ctx.textAlign="left",this.ctx.textBaseline="alphabetic",a=this.fontMetrics.getMetrics(s,i),o=a.baseline,Q=a.middle,g=r.paintOrder,t.textBounds.forEach(function(w){g.forEach(function(l){switch(l){case 0:c.ctx.fillStyle=R(r.color),c.renderTextWithLetterSpacing(w,r.letterSpacing,o);var H=r.textShadow;H.length&&w.text.trim().length&&(H.slice(0).reverse().forEach(function(F){c.ctx.shadowColor=R(F.color),c.ctx.shadowOffsetX=F.offsetX.number*c.options.scale,c.ctx.shadowOffsetY=F.offsetY.number*c.options.scale,c.ctx.shadowBlur=F.blur.number,c.renderTextWithLetterSpacing(w,r.letterSpacing,o)}),c.ctx.shadowColor="",c.ctx.shadowOffsetX=0,c.ctx.shadowOffsetY=0,c.ctx.shadowBlur=0),r.textDecorationLine.length&&(c.ctx.fillStyle=R(r.textDecorationColor||r.color),r.textDecorationLine.forEach(function(F){switch(F){case 1:c.ctx.fillRect(w.bounds.left,Math.round(w.bounds.top+o),w.bounds.width,1);break;case 2:c.ctx.fillRect(w.bounds.left,Math.round(w.bounds.top),w.bounds.width,1);break;case 3:c.ctx.fillRect(w.bounds.left,Math.ceil(w.bounds.top+Q),w.bounds.width,1);break}}));break;case 1:r.webkitTextStrokeWidth&&w.text.trim().length&&(c.ctx.strokeStyle=R(r.webkitTextStrokeColor),c.ctx.lineWidth=r.webkitTextStrokeWidth,c.ctx.lineJoin=window.chrome?"miter":"round",c.ctx.strokeText(w.text,w.bounds.left,w.bounds.top+o)),c.ctx.strokeStyle="",c.ctx.lineWidth=0,c.ctx.lineJoin="miter";break}})}),[2]})})},A.prototype.renderReplacedElement=function(t,r,B){if(B&&t.intrinsicWidth>0&&t.intrinsicHeight>0){var n=fr(t),s=lr(r);this.path(s),this.ctx.save(),this.ctx.clip(),this.ctx.drawImage(B,0,0,t.intrinsicWidth,t.intrinsicHeight,n.left,n.top,n.width,n.height),this.ctx.restore()}},A.prototype.renderNodeContent=function(t){return J(this,void 0,void 0,function(){var r,B,n,s,i,a,h,h,o,Q,g,c,p,u,w,d,l,H,F,h,m,p,d;return X(this,function(f){switch(f.label){case 0:this.applyEffects(t.getEffects(4)),r=t.container,B=t.curves,n=r.styles,s=0,i=r.textNodes,f.label=1;case 1:return s0&&_>0&&(y=n.ctx.createPattern(d,"repeat"),n.renderRepeat(M,y,W,Z))):Xa(Q)&&(E=Ut(t,r,[null,null,null]),M=E[0],Y=E[1],j=E[2],b=E[3],_=E[4],IA=Q.position.length===0?[Pr]:Q.position,W=D(IA[0],b),Z=D(IA[IA.length-1],_),SA=Ga(Q,W,Z,b,_),iA=SA[0],vA=SA[1],iA>0&&vA>0&&(TA=n.ctx.createRadialGradient(Y+W,j+Z,0,Y+W,j+Z,iA),dB(Q.stops,iA*2).forEach(function(Ee){return TA.addColorStop(Ee.stop,R(Ee.color))}),n.path(M),n.ctx.fillStyle=TA,iA!==vA?(OA=t.bounds.left+.5*t.bounds.width,wA=t.bounds.top+.5*t.bounds.height,MA=vA/iA,lA=1/MA,n.ctx.save(),n.ctx.translate(OA,wA),n.ctx.transform(1,0,0,MA,0,0),n.ctx.translate(-OA,-wA),n.ctx.fillRect(Y,lA*(j-wA)+wA,b,_*lA),n.ctx.restore()):n.ctx.fill())),jA.label=6;case 6:return r--,[2]}})},n=this,s=0,i=t.styles.backgroundImage.slice(0).reverse(),o.label=1;case 1:return s0?Q.style!==2?[3,5]:[4,this.renderDashedDottedBorder(Q.color,Q.width,i,t.curves,2)]:[3,11]):[3,13];case 4:return c.sent(),[3,11];case 5:return Q.style!==3?[3,7]:[4,this.renderDashedDottedBorder(Q.color,Q.width,i,t.curves,3)];case 6:return c.sent(),[3,11];case 7:return Q.style!==4?[3,9]:[4,this.renderDoubleBorder(Q.color,Q.width,i,t.curves)];case 8:return c.sent(),[3,11];case 9:return[4,this.renderSolidBorder(Q.color,i,t.curves)];case 10:c.sent(),c.label=11;case 11:i++,c.label=12;case 12:return a++,[3,3];case 13:return[2]}})})},A.prototype.renderDashedDottedBorder=function(t,r,B,n,s){return J(this,void 0,void 0,function(){var i,a,o,Q,g,c,u,w,l,H,F,h,m,p,d,f,d,f;return X(this,function(v){return this.ctx.save(),i=ZQ(n,B),a=bn(n,B),s===2&&(this.path(a),this.ctx.clip()),eA(a[0])?(o=a[0].start.x,Q=a[0].start.y):(o=a[0].x,Q=a[0].y),eA(a[1])?(g=a[1].end.x,c=a[1].end.y):(g=a[1].x,c=a[1].y),B===0||B===2?u=Math.abs(o-g):u=Math.abs(Q-c),this.ctx.beginPath(),s===3?this.formatPath(i):this.formatPath(a.slice(0,2)),w=r<3?r*3:r*2,l=r<3?r*2:r,s===3&&(w=r,l=r),H=!0,u<=w*2?H=!1:u<=w*2+l?(F=u/(2*w+l),w*=F,l*=F):(h=Math.floor((u+l)/(w+l)),m=(u-h*w)/(h-1),p=(u-(h+1)*w)/h,l=p<=0||Math.abs(l-m){try{JSON.parse(e.data).type==="refresh"&&location.reload()}catch{}}),qA.addEventListener("close",()=>setTimeout(Tn,2e3))}function Ft(e){const A=e.target;A.closest("[data-sidecar-pill]")||(A.style.outline="2px solid #89b4fa")}function ht(e){e.target.style.outline=""}async function dt(e){const A=e.target;if(A.closest("[data-sidecar-pill]"))return;e.preventDefault(),e.stopPropagation();const t=Xn(A),r=await Cg(A);qA==null||qA.send(JSON.stringify({type:"element-selected",selector:t,screenshot:r})),Ug.setActive(!1),document.removeEventListener("mouseover",Ft),document.removeEventListener("mouseout",ht),document.removeEventListener("click",dt,!0)}const Ug=Vn(e=>{e?(document.addEventListener("mouseover",Ft),document.addEventListener("mouseout",ht),document.addEventListener("click",dt,!0)):(document.removeEventListener("mouseover",Ft),document.removeEventListener("mouseout",ht),document.removeEventListener("click",dt,!0))});Tn()})(); diff --git a/sidecar-client/package.json b/sidecar-client/package.json new file mode 100644 index 0000000..12027e1 --- /dev/null +++ b/sidecar-client/package.json @@ -0,0 +1,21 @@ +{ + "name": "@browser-sidecar/sidecar-client", + "version": "0.0.1", + "private": true, + "type": "module", + "scripts": { + "build": "vite build", + "test": "vitest run" + }, + "dependencies": { + "html2canvas": "^1.4.1", + "vanjs-core": "^1.6.0" + }, + "devDependencies": { + "@vitest/browser": "^4.1.8", + "jsdom": "^29.1.1", + "typescript": "^5.8.3", + "vite": "^6.3.5", + "vitest": "^3.1.3" + } +} diff --git a/sidecar-client/src/index.ts b/sidecar-client/src/index.ts new file mode 100644 index 0000000..67f86a2 --- /dev/null +++ b/sidecar-client/src/index.ts @@ -0,0 +1,67 @@ +import { mountPill } from "./pill"; +import { buildSelector } from "./selector"; +import { captureScreenshot } from "./screenshot"; + +const WS_URL = (() => { + const proto = location.protocol === "https:" ? "wss:" : "ws:"; + return `${proto}//${location.host}/sidecar/ws`; +})(); + +let ws: WebSocket | null = null; +let selectionActive = false; + +function connect() { + ws = new WebSocket(WS_URL); + ws.addEventListener("message", (e) => { + try { + const msg = JSON.parse(e.data as string) as { type: string }; + if (msg.type === "refresh") location.reload(); + } catch { + // ignore malformed messages + } + }); + ws.addEventListener("close", () => setTimeout(connect, 2000)); +} + +function onMouseOver(e: MouseEvent) { + const target = e.target as HTMLElement; + if (target.closest("[data-sidecar-pill]")) return; + target.style.outline = "2px solid #89b4fa"; +} + +function onMouseOut(e: MouseEvent) { + (e.target as HTMLElement).style.outline = ""; +} + +async function onClick(e: MouseEvent) { + const target = e.target as HTMLElement; + if (target.closest("[data-sidecar-pill]")) return; + e.preventDefault(); + e.stopPropagation(); + + const selector = buildSelector(target); + const screenshot = await captureScreenshot(target); + + ws?.send(JSON.stringify({ type: "element-selected", selector, screenshot })); + + selectionActive = false; + pill.setActive(false); + document.removeEventListener("mouseover", onMouseOver); + document.removeEventListener("mouseout", onMouseOut); + document.removeEventListener("click", onClick, true); +} + +const pill = mountPill((active) => { + selectionActive = active; + if (active) { + document.addEventListener("mouseover", onMouseOver); + document.addEventListener("mouseout", onMouseOut); + document.addEventListener("click", onClick, true); + } else { + document.removeEventListener("mouseover", onMouseOver); + document.removeEventListener("mouseout", onMouseOut); + document.removeEventListener("click", onClick, true); + } +}); + +connect(); diff --git a/sidecar-client/src/pill.ts b/sidecar-client/src/pill.ts new file mode 100644 index 0000000..a126391 --- /dev/null +++ b/sidecar-client/src/pill.ts @@ -0,0 +1,57 @@ +import van from "vanjs-core"; + +const PILL_STYLES = ` + :host { all: initial; } + .pill { + display: flex; align-items: center; gap: 8px; + background: #1e1e2e; border-radius: 6px; + padding: 6px 12px; cursor: pointer; + font-family: monospace; font-size: 12px; + box-shadow: 0 2px 8px rgba(0,0,0,0.4); + user-select: none; + } + .dot { + width: 8px; height: 8px; border-radius: 50%; + transition: background 0.15s; + } + .dot.off { background: #6c7086; } + .dot.on { background: #a6e3a1; } + .label { color: #cdd6f4; } +`; + +export interface Pill { + setActive(v: boolean): void; +} + +export function mountPill(onToggle: (active: boolean) => void): Pill { + const { div, span, style } = van.tags; + const active = van.state(false); + + const host = document.createElement("div"); + host.setAttribute("data-sidecar-pill", ""); + host.style.cssText = + "position:fixed;bottom:16px;left:16px;z-index:2147483647;pointer-events:auto"; + document.body.appendChild(host); + + const shadow = host.attachShadow({ mode: "open" }); + + const pill = div( + { + class: "pill", + onclick: () => { + active.val = !active.val; + onToggle(active.val); + }, + }, + span({ class: () => `dot ${active.val ? "on" : "off"}` }), + span({ class: "label" }, "Select"), + ); + + van.add(shadow, style(PILL_STYLES), pill); + + return { + setActive(v: boolean) { + active.val = v; + }, + }; +} diff --git a/sidecar-client/src/screenshot.ts b/sidecar-client/src/screenshot.ts new file mode 100644 index 0000000..e3ea583 --- /dev/null +++ b/sidecar-client/src/screenshot.ts @@ -0,0 +1,15 @@ +import html2canvas from "html2canvas"; + +export async function captureScreenshot(el: HTMLElement): Promise { + const rect = el.getBoundingClientRect(); + const canvas = await html2canvas(document.body, { + x: rect.left + window.scrollX, + y: rect.top + window.scrollY, + width: rect.width, + height: rect.height, + useCORS: true, + logging: false, + }); + // Remove the "data:image/png;base64," prefix — Go decodes raw base64 + return canvas.toDataURL("image/png").split(",")[1] ?? ""; +} diff --git a/sidecar-client/src/selector.test.ts b/sidecar-client/src/selector.test.ts new file mode 100644 index 0000000..7dc6339 --- /dev/null +++ b/sidecar-client/src/selector.test.ts @@ -0,0 +1,69 @@ +import { describe, it, expect } from "vitest"; +import { buildSelector, DYNAMIC_CLASS_RE } from "./selector"; + +function el(tag: string, attrs: Record = {}): Element { + const e = document.createElement(tag); + if (attrs.id) e.id = attrs.id; + if (attrs.class) e.className = attrs.class; + return e; +} + +describe("buildSelector", () => { + it("returns tag name for element with no id or classes", () => { + expect(buildSelector(el("div"))).toBe("div"); + }); + + it("returns tag name for a detached bare element with no id, no classes, and no ancestors", () => { + expect(buildSelector(el("span"))).toBe("span"); + }); + + it("returns 'body' when passed document.body", () => { + expect(buildSelector(document.body)).toBe("body"); + }); + + it("stops at id and uses #id", () => { + const e = el("div", { id: "main" }); + expect(buildSelector(e)).toBe("#main"); + }); + + it("includes stable class names", () => { + const e = el("button", { class: "btn primary" }); + expect(buildSelector(e)).toBe("button.btn.primary"); + }); + + it("skips dynamic CSS-module-like class names (requires prefix, dash, then at least one digit in suffix)", () => { + // regex: /^[a-z]+-(?=[a-z0-9]*\d)[a-z0-9]{4,}$/i — digit lookahead required + const e = el("div", { class: "card-header abc-1234 stable" }); + expect(buildSelector(e)).toBe("div.card-header.stable"); + }); + + it("limits to first two stable classes", () => { + const e = el("div", { class: "a b c d" }); + expect(buildSelector(e)).toBe("div.a.b"); + }); + + it("walks ancestor chain up to body", () => { + const parent = el("section", { class: "container" }); + const child = el("p"); + parent.appendChild(child); + document.body.appendChild(parent); + expect(buildSelector(child)).toBe("section.container > p"); + document.body.removeChild(parent); + }); +}); + +describe("DYNAMIC_CLASS_RE", () => { + it("matches class names with prefix-dash-alphanumeric-suffix containing a digit", () => { + expect(DYNAMIC_CLASS_RE.test("abc-1234")).toBe(true); + expect(DYNAMIC_CLASS_RE.test("btn-a1b2")).toBe(true); + }); + + it("does not match suffix with no digit", () => { + expect(DYNAMIC_CLASS_RE.test("card-header")).toBe(false); + expect(DYNAMIC_CLASS_RE.test("abc-abcd")).toBe(false); + }); + + it("does not match suffix shorter than 4 characters", () => { + expect(DYNAMIC_CLASS_RE.test("abc-12")).toBe(false); + }); +}); diff --git a/sidecar-client/src/selector.ts b/sidecar-client/src/selector.ts new file mode 100644 index 0000000..98d7bea --- /dev/null +++ b/sidecar-client/src/selector.ts @@ -0,0 +1,30 @@ +// browser-only +export const DYNAMIC_CLASS_RE = /^[a-z]+-(?=[a-z0-9]*\d)[a-z0-9]{4,}$/i; + +const MAX_CLASSES = 2; + +export function buildSelector(el: Element): string { + if (el === document.body) return "body"; + + const parts: string[] = []; + let current: Element | null = el; + + while (current && current !== document.body) { + if (current.id) { + parts.unshift(`#${current.id}`); + break; + } + + const tag = current.tagName.toLowerCase(); + const stableClasses = Array.from(current.classList) + .filter((c) => !DYNAMIC_CLASS_RE.test(c)) + .slice(0, MAX_CLASSES); + + const segment = + stableClasses.length > 0 ? `${tag}.${stableClasses.join(".")}` : tag; + parts.unshift(segment); + current = current.parentElement; + } + + return parts.join(" > ") || el.tagName.toLowerCase(); +} diff --git a/sidecar-client/tsconfig.json b/sidecar-client/tsconfig.json new file mode 100644 index 0000000..36f26ca --- /dev/null +++ b/sidecar-client/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "lib": ["ES2020", "DOM"], + "outDir": "dist" + }, + "include": ["src"] +} diff --git a/sidecar-client/vite.config.ts b/sidecar-client/vite.config.ts new file mode 100644 index 0000000..6998022 --- /dev/null +++ b/sidecar-client/vite.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from "vite"; + +export default defineConfig({ + build: { + lib: { + entry: "src/index.ts", + name: "SidecarClient", + formats: ["iife"], + fileName: () => "client.js", + }, + outDir: "dist", + minify: true, + rollupOptions: { + output: { + inlineDynamicImports: true, + }, + }, + }, +}); diff --git a/sidecar-client/vitest.config.ts b/sidecar-client/vitest.config.ts new file mode 100644 index 0000000..9f6250a --- /dev/null +++ b/sidecar-client/vitest.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + environment: "jsdom", + }, +});