From b33fce53ddc381dba5266d9fc4895a5eed662b52 Mon Sep 17 00:00:00 2001 From: Adam Lamers Date: Sat, 28 Mar 2026 22:05:24 -0400 Subject: [PATCH] initial commit --- .cursor/rules/spacetimedb-typescript.mdc | 659 ++ .cursor/rules/spacetimedb.mdc | 116 + .env.local | 23 + .github/copilot-instructions.md | 766 ++ .gitignore | 47 + .windsurfrules | 766 ++ AGENTS.md | 766 ++ CHANGELOG.md | 29 + CLAUDE.md | 766 ++ LICENSE | 202 + README.md | 67 + dist/assets/index-DnMf931V.js | 86 + dist/assets/index-a-MKc3No.css | 1 + dist/index.html | 14 + dist/vite.svg | 1 + index.html | 13 + package.json | 45 + pnpm-lock.yaml | 2993 ++++++++ public/vite.svg | 1 + spacetime.json | 8 + spacetime.local.json | 3 + spacetimedb/dist/bundle.js | 6385 +++++++++++++++++ spacetimedb/node_modules/.bin/tsc | 21 + spacetimedb/node_modules/.bin/tsserver | 21 + spacetimedb/node_modules/.modules.yaml | 51 + .../.pnpm-workspace-state-v1.json | 25 + spacetimedb/node_modules/spacetimedb | 1 + spacetimedb/node_modules/typescript | 1 + spacetimedb/package-lock.json | 113 + spacetimedb/package.json | 16 + spacetimedb/pnpm-lock.yaml | 107 + spacetimedb/src/index.ts | 430 ++ spacetimedb/tsconfig.json | 28 + src/.gitattributes | 1 + src/App.css | 455 ++ src/App.integration.test.tsx | 76 + src/App.tsx | 653 ++ src/assets/react.svg | 1 + src/index.css | 76 + src/main.tsx | 81 + src/module_bindings/channel_table.ts | 24 + src/module_bindings/create_channel_reducer.ts | 17 + src/module_bindings/create_server_reducer.ts | 15 + src/module_bindings/create_thread_reducer.ts | 17 + src/module_bindings/ice_candidate_table.ts | 18 + src/module_bindings/index.ts | 253 + src/module_bindings/join_voice_reducer.ts | 15 + src/module_bindings/leave_voice_reducer.ts | 13 + src/module_bindings/login_reducer.ts | 16 + src/module_bindings/message_table.ts | 20 + src/module_bindings/register_reducer.ts | 16 + src/module_bindings/sdp_answer_table.ts | 18 + src/module_bindings/sdp_offer_table.ts | 18 + .../send_ice_candidate_reducer.ts | 17 + src/module_bindings/send_message_reducer.ts | 17 + .../send_sdp_answer_reducer.ts | 17 + src/module_bindings/send_sdp_offer_reducer.ts | 17 + src/module_bindings/server_table.ts | 17 + src/module_bindings/set_name_reducer.ts | 15 + src/module_bindings/thread_table.ts | 18 + src/module_bindings/types.ts | 95 + src/module_bindings/types/procedures.ts | 10 + src/module_bindings/types/reducers.ts | 34 + src/module_bindings/user_table.ts | 21 + src/module_bindings/voice_state_table.ts | 16 + src/setupTests.ts | 1 + src/useWebRTC.ts | 205 + tsconfig.app.json | 25 + tsconfig.json | 7 + tsconfig.node.json | 24 + vite.config.ts | 14 + vitest.config.ts | 13 + 72 files changed, 16957 insertions(+) create mode 100644 .cursor/rules/spacetimedb-typescript.mdc create mode 100644 .cursor/rules/spacetimedb.mdc create mode 100644 .env.local create mode 100644 .github/copilot-instructions.md create mode 100644 .gitignore create mode 100644 .windsurfrules create mode 100644 AGENTS.md create mode 100644 CHANGELOG.md create mode 100644 CLAUDE.md create mode 100644 LICENSE create mode 100644 README.md create mode 100644 dist/assets/index-DnMf931V.js create mode 100644 dist/assets/index-a-MKc3No.css create mode 100644 dist/index.html create mode 100644 dist/vite.svg create mode 100644 index.html create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 public/vite.svg create mode 100644 spacetime.json create mode 100644 spacetime.local.json create mode 100644 spacetimedb/dist/bundle.js create mode 100755 spacetimedb/node_modules/.bin/tsc create mode 100755 spacetimedb/node_modules/.bin/tsserver create mode 100644 spacetimedb/node_modules/.modules.yaml create mode 100644 spacetimedb/node_modules/.pnpm-workspace-state-v1.json create mode 120000 spacetimedb/node_modules/spacetimedb create mode 120000 spacetimedb/node_modules/typescript create mode 100644 spacetimedb/package-lock.json create mode 100644 spacetimedb/package.json create mode 100644 spacetimedb/pnpm-lock.yaml create mode 100644 spacetimedb/src/index.ts create mode 100644 spacetimedb/tsconfig.json create mode 100644 src/.gitattributes create mode 100644 src/App.css create mode 100644 src/App.integration.test.tsx create mode 100644 src/App.tsx create mode 100644 src/assets/react.svg create mode 100644 src/index.css create mode 100644 src/main.tsx create mode 100644 src/module_bindings/channel_table.ts create mode 100644 src/module_bindings/create_channel_reducer.ts create mode 100644 src/module_bindings/create_server_reducer.ts create mode 100644 src/module_bindings/create_thread_reducer.ts create mode 100644 src/module_bindings/ice_candidate_table.ts create mode 100644 src/module_bindings/index.ts create mode 100644 src/module_bindings/join_voice_reducer.ts create mode 100644 src/module_bindings/leave_voice_reducer.ts create mode 100644 src/module_bindings/login_reducer.ts create mode 100644 src/module_bindings/message_table.ts create mode 100644 src/module_bindings/register_reducer.ts create mode 100644 src/module_bindings/sdp_answer_table.ts create mode 100644 src/module_bindings/sdp_offer_table.ts create mode 100644 src/module_bindings/send_ice_candidate_reducer.ts create mode 100644 src/module_bindings/send_message_reducer.ts create mode 100644 src/module_bindings/send_sdp_answer_reducer.ts create mode 100644 src/module_bindings/send_sdp_offer_reducer.ts create mode 100644 src/module_bindings/server_table.ts create mode 100644 src/module_bindings/set_name_reducer.ts create mode 100644 src/module_bindings/thread_table.ts create mode 100644 src/module_bindings/types.ts create mode 100644 src/module_bindings/types/procedures.ts create mode 100644 src/module_bindings/types/reducers.ts create mode 100644 src/module_bindings/user_table.ts create mode 100644 src/module_bindings/voice_state_table.ts create mode 100644 src/setupTests.ts create mode 100644 src/useWebRTC.ts create mode 100644 tsconfig.app.json create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json create mode 100644 vite.config.ts create mode 100644 vitest.config.ts diff --git a/.cursor/rules/spacetimedb-typescript.mdc b/.cursor/rules/spacetimedb-typescript.mdc new file mode 100644 index 0000000..22503fb --- /dev/null +++ b/.cursor/rules/spacetimedb-typescript.mdc @@ -0,0 +1,659 @@ +--- +description: "⛔ MANDATORY: Read this ENTIRE file before writing ANY SpacetimeDB TypeScript code. Contains critical SDK patterns and HALLUCINATED APIs to avoid." +globs: **/*.ts,**/*.tsx,**/*.js,**/*.jsx +alwaysApply: true +--- + +# SpacetimeDB TypeScript SDK + +## ⛔ HALLUCINATED APIs — DO NOT USE + +**These APIs DO NOT EXIST. LLMs frequently hallucinate them.** + +```typescript +// ❌ WRONG PACKAGE — does not exist +import { SpacetimeDBClient } from "@clockworklabs/spacetimedb-sdk"; + +// ❌ WRONG — these methods don't exist +SpacetimeDBClient.connect(...); +SpacetimeDBClient.call("reducer_name", [...]); +connection.call("reducer_name", [arg1, arg2]); + +// ❌ WRONG — positional reducer arguments +conn.reducers.doSomething("value"); // WRONG! + +// ❌ WRONG — static methods on generated types don't exist +User.filterByName('alice'); +Message.findById(123n); +tables.user.filter(u => u.name === 'alice'); // No .filter() on tables object! +``` + +### ✅ CORRECT PATTERNS: + +```typescript +// ✅ CORRECT IMPORTS +import { DbConnection, tables } from './module_bindings'; // Generated! +import { SpacetimeDBProvider, useTable, Identity } from 'spacetimedb/react'; + +// ✅ CORRECT REDUCER CALLS — object syntax, not positional! +conn.reducers.doSomething({ value: 'test' }); +conn.reducers.updateItem({ itemId: 1n, newValue: 42 }); + +// ✅ CORRECT DATA ACCESS — useTable returns [rows, isLoading] +const [items, isLoading] = useTable(tables.item); +``` + +### ⛔ DO NOT: +- **Invent hooks** like `useItems()`, `useData()` — use `useTable(tables.tableName)` +- **Import from fake packages** — only `spacetimedb`, `spacetimedb/react`, `./module_bindings` + +--- + +## 1) Common Mistakes Table + +### Server-side errors + +| Wrong | Right | Error | +|-------|-------|-------| +| Missing `package.json` | Create `package.json` | "could not detect language" | +| Missing `tsconfig.json` | Create `tsconfig.json` | "TsconfigNotFound" | +| Entrypoint not at `src/index.ts` | Use `src/index.ts` | Module won't bundle | +| `indexes` in COLUMNS (2nd arg) | `indexes` in OPTIONS (1st arg) | "reading 'tag'" error | +| Index without `algorithm` | `algorithm: 'btree'` | "reading 'tag'" error | +| `filter({ ownerId })` | `filter(ownerId)` | "does not exist in type 'Range'" | +| `.filter()` on unique column | `.find()` on unique column | TypeError | +| `insert({ ...without id })` | `insert({ id: 0n, ... })` | "Property 'id' is missing" | +| `const id = table.insert(...)` | `const row = table.insert(...)` | `.insert()` returns ROW, not ID | +| `.unique()` + explicit index | Just use `.unique()` | "name is used for multiple entities" | +| Index on `.primaryKey()` column | Don't — already indexed | "name is used for multiple entities" | +| Same index name in multiple tables | Prefix with table name | "name is used for multiple entities" | +| `.indexName.filter()` after removing index | Use `.iter()` + manual filter | "Cannot read properties of undefined" | +| Import spacetimedb from index.ts | Import from schema.ts | "Cannot access before initialization" | +| Multi-column index `.filter()` | **⚠️ BROKEN** — use single-column | PANIC or silent empty results | +| `JSON.stringify({ id: row.id })` | Convert BigInt first: `{ id: row.id.toString() }` | "Do not know how to serialize a BigInt" | +| `ScheduleAt.Time(timestamp)` | `ScheduleAt.time(timestamp)` (lowercase) | "ScheduleAt.Time is not a function" | +| `ctx.db.foo.myIndexName.filter()` | Use exact name: `ctx.db.foo.my_index_name.filter()` | "Cannot read properties of undefined" | +| `.iter()` in views | Use index lookups | Severe performance issues (re-evaluates on any change) | +| `ctx.db` in procedures | `ctx.withTx(tx => tx.db...)` | Procedures need explicit transactions | +| `ctx.myTable` in procedure tx | `tx.db.myTable` | Wrong context variable | + +### Client-side errors + +| Wrong | Right | Error | +|-------|-------|-------| +| `@spacetimedb/sdk` | `spacetimedb` | 404 / missing subpath | +| `conn.reducers.foo("val")` | `conn.reducers.foo({ param: "val" })` | Wrong reducer syntax | +| Inline `connectionBuilder` | `useMemo(() => ..., [])` | Reconnects every render | +| `const rows = useTable(table)` | `const [rows, isLoading] = useTable(table)` | Tuple destructuring | +| Optimistic UI updates | Let subscriptions drive state | Desync issues | +| `` | `connectionBuilder={...}` | Wrong prop name | + +--- + +## 2) Table Definition (CRITICAL) + +**`table()` takes TWO arguments: `table(OPTIONS, COLUMNS)`** + +```typescript +import { schema, table, t } from 'spacetimedb/server'; + +// ❌ WRONG — indexes in COLUMNS causes "reading 'tag'" error +export const Task = table({ name: 'task' }, { + id: t.u64().primaryKey().autoInc(), + ownerId: t.identity(), + indexes: [{ name: 'by_owner', algorithm: 'btree', columns: ['ownerId'] }] // ❌ WRONG! +}); + +// ✅ RIGHT — indexes in OPTIONS (first argument) +export const Task = table({ + name: 'task', + public: true, + indexes: [{ name: 'by_owner', algorithm: 'btree', columns: ['ownerId'] }] +}, { + id: t.u64().primaryKey().autoInc(), + ownerId: t.identity(), + title: t.string(), + createdAt: t.timestamp(), +}); +``` + +### Column types +```typescript +t.identity() // User identity (primary key for per-user tables) +t.u64() // Unsigned 64-bit integer (use for IDs) +t.string() // Text +t.bool() // Boolean +t.timestamp() // Timestamp (use ctx.timestamp for current time) +t.scheduleAt() // For scheduled tables only + +// Product types (nested objects) — use t.object, NOT t.struct +const Point = t.object('Point', { x: t.i32(), y: t.i32() }); + +// Sum types (tagged unions) — use t.enum, NOT t.sum +const Shape = t.enum('Shape', { circle: t.i32(), rectangle: Point }); +// Values use { tag: 'circle', value: 10 } or { tag: 'rectangle', value: { x: 1, y: 2 } } + +// Modifiers +t.string().optional() // Nullable +t.u64().primaryKey() // Primary key +t.u64().primaryKey().autoInc() // Auto-increment primary key +``` + +> ⚠️ **BIGINT SYNTAX:** All `u64`, `i64`, and ID fields use JavaScript BigInt. +> - Literals: `0n`, `1n`, `100n` (NOT `0`, `1`, `100`) +> - Comparisons: `row.id === 5n` (NOT `row.id === 5`) +> - Arithmetic: `row.count + 1n` (NOT `row.count + 1`) + +### Auto-increment placeholder +```typescript +// ✅ MUST provide 0n placeholder for auto-inc fields +ctx.db.task.insert({ id: 0n, ownerId: ctx.sender, title: 'New', createdAt: ctx.timestamp }); +``` + +### Insert returns ROW, not ID +```typescript +// ❌ WRONG +const id = ctx.db.task.insert({ ... }); + +// ✅ RIGHT +const row = ctx.db.task.insert({ ... }); +const newId = row.id; // Extract .id from returned row +``` + +### Schema export (CRITICAL) +```typescript +// At end of schema.ts — schema() takes exactly ONE argument: an object +const spacetimedb = schema({ table1, table2, table3 }); +export default spacetimedb; + +// ❌ WRONG — never pass tables directly or as multiple args +schema(myTable); // WRONG! +schema(t1, t2, t3); // WRONG! +``` + +--- + +## 3) Index Access + +### TypeScript Query Patterns + +```typescript +// 1. PRIMARY KEY — use .pkColumn.find() +const user = ctx.db.user.identity.find(ctx.sender); +const msg = ctx.db.message.id.find(messageId); + +// 2. EXPLICIT INDEX — use .indexName.filter(value) +const msgs = [...ctx.db.message.message_room_id.filter(roomId)]; + +// 3. NO INDEX — use .iter() + manual filter +for (const m of ctx.db.roomMember.iter()) { + if (m.roomId === roomId) { /* ... */ } +} +``` + +### Index Definition Syntax + +```typescript +// In table OPTIONS (first argument), not columns +export const Message = table({ + name: 'message', + public: true, + indexes: [{ name: 'message_room_id', algorithm: 'btree', columns: ['roomId'] }] +}, { + id: t.u64().primaryKey().autoInc(), + roomId: t.u64(), + // ... +}); +``` + +### Naming conventions + +**Table names — automatic transformation:** +- Schema: `table({ name: 'my_messages' })` +- Access: `ctx.db.myMessages` (automatic snake_case → camelCase) + +**Index names — NO transformation, use EXACTLY as defined:** +```typescript +// Schema definition +indexes: [{ name: 'canvas_member_canvas_id', algorithm: 'btree', columns: ['canvasId'] }] + +// ❌ WRONG — don't assume camelCase transformation +ctx.db.canvasMember.canvasMember_canvas_id.filter(...) // WRONG! +ctx.db.canvasMember.canvasMemberCanvasId.filter(...) // WRONG! + +// ✅ RIGHT — use exact name from schema +ctx.db.canvasMember.canvas_member_canvas_id.filter(...) +``` + +> ⚠️ **Index names are used VERBATIM** — pick a convention (snake_case or camelCase) and stick with it. + +**Index naming pattern — use `{tableName}_{columnName}`:** +```typescript +// ✅ GOOD — unique names across entire module +indexes: [{ name: 'message_room_id', algorithm: 'btree', columns: ['roomId'] }] +indexes: [{ name: 'reaction_message_id', algorithm: 'btree', columns: ['messageId'] }] + +// ❌ BAD — will collide if multiple tables use same index name +indexes: [{ name: 'by_owner', ... }] // in Task table +indexes: [{ name: 'by_owner', ... }] // in Note table — CONFLICT! +``` + +**Client-side table names:** +- Check generated `module_bindings/index.ts` for exact export names +- Usage: `useTable(tables.MyMessages)` or `tables.myMessages` (varies by SDK version) + +### Filter vs Find +```typescript +// Filter takes VALUE directly, not object — returns iterator +const rows = [...ctx.db.task.by_owner.filter(ownerId)]; + +// Unique columns use .find() — returns single row or undefined +const row = ctx.db.player.identity.find(ctx.sender); +``` + +### ⚠️ Multi-column indexes are BROKEN +```typescript +// ❌ DON'T — causes PANIC +ctx.db.scores.by_player_level.filter(playerId); + +// ✅ DO — use single-column index + manual filter +for (const row of ctx.db.scores.by_player.filter(playerId)) { + if (row.level === targetLevel) { /* ... */ } +} +``` + +--- + +## 4) Reducers + +### Definition syntax (CRITICAL) +**Reducer name comes from the export — NOT from a string argument.** Use `reducer(params, fn)` or `reducer(fn)`. + +```typescript +import spacetimedb from './schema'; +import { t, SenderError } from 'spacetimedb/server'; + +// ✅ CORRECT — export const name = spacetimedb.reducer(params, fn) +export const reducer_name = spacetimedb.reducer({ param1: t.string(), param2: t.u64() }, (ctx, { param1, param2 }) => { + // Validation + if (!param1) throw new SenderError('param1 required'); + + // Access tables via ctx.db + const row = ctx.db.myTable.primaryKey.find(param2); + + // Mutations + ctx.db.myTable.insert({ ... }); + ctx.db.myTable.primaryKey.update({ ...row, newField: value }); + ctx.db.myTable.primaryKey.delete(param2); +}); + +// No params: export const init = spacetimedb.reducer((ctx) => { ... }); +``` + +```typescript +// ❌ WRONG — reducer('name', params, fn) does NOT exist +spacetimedb.reducer('reducer_name', { param1: t.string() }, (ctx, { param1 }) => { ... }); +``` + +### Update pattern (CRITICAL) +```typescript +// ✅ CORRECT — spread existing row, override specific fields +const existing = ctx.db.task.id.find(taskId); +if (!existing) throw new SenderError('Task not found'); +ctx.db.task.id.update({ ...existing, title: newTitle, updatedAt: ctx.timestamp }); + +// ❌ WRONG — partial update nulls out other fields! +ctx.db.task.id.update({ id: taskId, title: newTitle }); +``` + +### Delete pattern +```typescript +// Delete by primary key VALUE (not row object) +ctx.db.task.id.delete(taskId); // taskId is the u64 value +ctx.db.player.identity.delete(ctx.sender); // delete by identity +``` + +### Lifecycle hooks +```typescript +spacetimedb.clientConnected((ctx) => { + // ctx.sender is the connecting identity + // Create/update user record, set online status, etc. +}); + +spacetimedb.clientDisconnected((ctx) => { + // Clean up: set offline status, remove ephemeral data, etc. +}); +``` + +### Snake_case to camelCase conversion +- Server: `export const do_something = spacetimedb.reducer(...)` — name from export +- Client: `conn.reducers.doSomething({ ... })` + +### Object syntax required +```typescript +// ❌ WRONG - positional +conn.reducers.doSomething('value'); + +// ✅ RIGHT - object +conn.reducers.doSomething({ param: 'value' }); +``` + +--- + +## 5) Scheduled Tables + +```typescript +// 1. Define table first (scheduled: () => reducer — pass the exported reducer) +export const CleanupJob = table({ + name: 'cleanup_job', + scheduled: () => run_cleanup // reducer defined below +}, { + scheduledId: t.u64().primaryKey().autoInc(), + scheduledAt: t.scheduleAt(), + targetId: t.u64(), // Your custom data +}); + +// 2. Define scheduled reducer (receives full row as arg) +export const run_cleanup = spacetimedb.reducer({ arg: CleanupJob.rowType }, (ctx, { arg }) => { + // arg.scheduledId, arg.targetId available + // Row is auto-deleted after reducer completes +}); + +// Schedule a job +import { ScheduleAt } from 'spacetimedb'; +const futureTime = ctx.timestamp.microsSinceUnixEpoch + 60_000_000n; // 60 seconds +ctx.db.cleanupJob.insert({ + scheduledId: 0n, + scheduledAt: ScheduleAt.time(futureTime), + targetId: someId +}); + +// Cancel a job by deleting the row +ctx.db.cleanupJob.scheduledId.delete(jobId); +``` + +--- + +## 6) Timestamps + +### Server-side +```typescript +import { Timestamp, ScheduleAt } from 'spacetimedb'; + +// Current time +ctx.db.item.insert({ id: 0n, createdAt: ctx.timestamp }); + +// Future time (add microseconds) +const future = ctx.timestamp.microsSinceUnixEpoch + 300_000_000n; // 5 minutes +``` + +### Client-side (CRITICAL) +**Timestamps are objects, not numbers:** +```typescript +// ❌ WRONG +const date = new Date(row.createdAt); +const date = new Date(Number(row.createdAt / 1000n)); + +// ✅ RIGHT +const date = new Date(Number(row.createdAt.microsSinceUnixEpoch / 1000n)); +``` + +### ScheduleAt on client +```typescript +// ScheduleAt is a tagged union +if (scheduleAt.tag === 'Time') { + const date = new Date(Number(scheduleAt.value.microsSinceUnixEpoch / 1000n)); +} +``` + +--- + +## 7) Data Visibility & Subscriptions + +**`public: true` exposes ALL rows to ALL clients.** + +| Scenario | Pattern | +|----------|---------| +| Everyone sees all rows | `public: true` | +| Users see only their data | Private table + filtered subscription | + +### Subscription patterns (client-side) +```typescript +// Subscribe to ALL public tables (simplest) +conn.subscriptionBuilder().subscribeToAll(); + +// Subscribe to specific tables with SQL +conn.subscriptionBuilder().subscribe([ + 'SELECT * FROM message', + 'SELECT * FROM room WHERE is_public = true', +]); + +// Handle subscription lifecycle +conn.subscriptionBuilder() + .onApplied(() => console.log('Initial data loaded')) + .onError((e) => console.error('Subscription failed:', e)) + .subscribeToAll(); +``` + +### Private table + view pattern (RECOMMENDED) + +**Views are the recommended approach** for controlling data visibility. They provide: +- Server-side filtering (reduces network traffic) +- Real-time updates when underlying data changes +- Full control over what data clients can access + +> ⚠️ **Do NOT use Row Level Security (RLS)** — it is deprecated. + +> ⚠️ **CRITICAL:** Procedural views (views that compute results in code) can ONLY access data via index lookups, NOT `.iter()`. +> If you need a view that scans/filters across many rows (including the entire table), return a **query** built with the query builder (`ctx.from...`). + +```typescript +// Private table with index on ownerId +export const PrivateData = table( + { name: 'private_data', + indexes: [{ name: 'by_owner', algorithm: 'btree', columns: ['ownerId'] }] + }, + { + id: t.u64().primaryKey().autoInc(), + ownerId: t.identity(), + secret: t.string() + } +); + +// ❌ BAD — .iter() causes performance issues (re-evaluates on ANY row change) +spacetimedb.view( + { name: 'my_data_slow', public: true }, + t.array(PrivateData.rowType), + (ctx) => [...ctx.db.privateData.iter()] // Works but VERY slow at scale +); + +// ✅ GOOD — index lookup enables targeted invalidation +spacetimedb.view( + { name: 'my_data', public: true }, + t.array(PrivateData.rowType), + (ctx) => [...ctx.db.privateData.by_owner.filter(ctx.sender)] +); +``` + +### Query builder view pattern (can scan) + +```typescript +// Query-builder views return a query; the SQL engine maintains the result incrementally. +// This can scan the whole table if needed (e.g. leaderboard-style queries). +spacetimedb.anonymousView( + { name: 'top_players', public: true }, + t.array(Player.rowType), + (ctx) => + ctx.from.player + .where(p => p.score.gt(1000)) +); +``` + +### ViewContext vs AnonymousViewContext +```typescript +// ViewContext — has ctx.sender, result varies per user (computed per-subscriber) +spacetimedb.view({ name: 'my_items', public: true }, t.array(Item.rowType), (ctx) => { + return [...ctx.db.item.by_owner.filter(ctx.sender)]; +}); + +// AnonymousViewContext — no ctx.sender, same result for everyone (shared, better perf) +spacetimedb.anonymousView({ name: 'leaderboard', public: true }, t.array(LeaderboardRow), (ctx) => { + return [...ctx.db.player.by_score.filter(/* top scores */)]; +}); +``` + +**Views require explicit subscription:** +```typescript +conn.subscriptionBuilder().subscribe([ + 'SELECT * FROM public_table', + 'SELECT * FROM my_data', // Views need explicit SQL! +]); +``` + +--- + +## 8) React Integration + +### Key patterns +```typescript +// Memoize connectionBuilder to prevent reconnects on re-render +const builder = useMemo(() => + DbConnection.builder() + .withUri(SPACETIMEDB_URI) + .withDatabaseName(MODULE_NAME) + .withToken(localStorage.getItem('auth_token') || undefined) + .onConnect(onConnect) + .onConnectError(onConnectError), + [] // Empty deps - only create once +); + +// useTable returns tuple [rows, isLoading] +const [rows, isLoading] = useTable(tables.myTable); + +// Compare identities using toHexString() +const isOwner = row.ownerId.toHexString() === myIdentity.toHexString(); +``` + +--- + +## 9) Procedures (Beta) + +**Procedures are for side effects (HTTP requests, etc.) that reducers can't do.** + +⚠️ Procedures are currently in beta. API may change. + +### Defining a procedure +**Procedure name comes from the export — NOT from a string argument.** Use `procedure(params, ret, fn)` or `procedure(ret, fn)`. + +```typescript +// ✅ CORRECT — export const name = spacetimedb.procedure(params, ret, fn) +export const fetch_external_data = spacetimedb.procedure( + { url: t.string() }, + t.string(), // return type + (ctx, { url }) => { + const response = ctx.http.fetch(url); + return response.text(); + } +); +``` + +### Database access in procedures + +⚠️ **CRITICAL: Procedures don't have `ctx.db`. Use `ctx.withTx()` for database access.** + +```typescript +spacetimedb.procedure({ url: t.string() }, t.unit(), (ctx, { url }) => { + // Fetch external data (outside transaction) + const response = ctx.http.fetch(url); + const data = response.text(); + + // ❌ WRONG — ctx.db doesn't exist in procedures + ctx.db.myTable.insert({ ... }); + + // ✅ RIGHT — use ctx.withTx() for database access + ctx.withTx(tx => { + tx.db.myTable.insert({ + id: 0n, + content: data, + fetchedAt: tx.timestamp, + fetchedBy: tx.sender, + }); + }); + + return {}; +}); +``` + +### Key differences from reducers +| Reducers | Procedures | +|----------|------------| +| `ctx.db` available directly | Must use `ctx.withTx(tx => tx.db...)` | +| Automatic transaction | Manual transaction management | +| No HTTP/network | `ctx.http.fetch()` available | +| No return values to caller | Can return data to caller | + +--- + +## 10) Project Structure + +### Server (`backend/spacetimedb/`) +``` +src/schema.ts → Tables, export spacetimedb +src/index.ts → Reducers, lifecycle, import schema +package.json → { "type": "module", "dependencies": { "spacetimedb": "^1.11.0" } } +tsconfig.json → Standard config +``` + +### Avoiding circular imports +``` +schema.ts → defines tables AND exports spacetimedb +index.ts → imports spacetimedb from ./schema, defines reducers +``` + +### Client (`client/`) +``` +src/module_bindings/ → Generated (spacetime generate) +src/main.tsx → Provider, connection setup +src/App.tsx → UI components +src/config.ts → MODULE_NAME, SPACETIMEDB_URI +``` + +--- + +## 11) Commands + +```bash +# Start local server +spacetime start + +# Publish module +spacetime publish --module-path + +# Clear database and republish +spacetime publish --clear-database -y --module-path + +# Generate bindings +spacetime generate --lang typescript --out-dir /src/module_bindings --module-path + +# View logs +spacetime logs +``` + +--- + +## 12) Hard Requirements + +**TypeScript-specific:** + +1. **`schema({ table })`** — takes exactly one object; never `schema(table)` or `schema(t1, t2, t3)` +2. **Reducer/procedure names from exports** — `export const name = spacetimedb.reducer(params, fn)`; never `reducer('name', ...)` +3. **Reducer calls use object syntax** — `{ param: 'value' }` not positional args +4. **Import `DbConnection` from `./module_bindings`** — not from `spacetimedb` +5. **DO NOT edit generated bindings** — regenerate with `spacetime generate` +6. **Indexes go in OPTIONS (1st arg)** — not in COLUMNS (2nd arg) of `table()` +7. **Use BigInt for u64/i64 fields** — `0n`, `1n`, not `0`, `1` +8. **Reducers are transactional** — they do not return data +9. **Reducers must be deterministic** — no filesystem, network, timers, random +10. **Views should use index lookups** — `.iter()` causes severe performance issues +11. **Procedures need `ctx.withTx()`** — `ctx.db` doesn't exist in procedures +12. **Sum type values** — use `{ tag: 'variant', value: payload }` not `{ variant: payload }` diff --git a/.cursor/rules/spacetimedb.mdc b/.cursor/rules/spacetimedb.mdc new file mode 100644 index 0000000..31cb456 --- /dev/null +++ b/.cursor/rules/spacetimedb.mdc @@ -0,0 +1,116 @@ +--- +description: "⛔ MANDATORY: Core SpacetimeDB concepts (all languages)." +globs: **/*.ts,**/*.tsx,**/*.js,**/*.jsx,**/*.rs,**/*.cs +alwaysApply: true +--- +# SpacetimeDB Rules (All Languages) + +## Migrating from 1.0 to 2.0? + +**If you are migrating existing SpacetimeDB 1.0 code to 2.0, apply `spacetimedb-migration-2.0.mdc` first.** It documents breaking changes (reducer callbacks → event tables, `name`→`accessor`, `sender()` method, etc.) and should be considered before other rules. + +--- + +## Language-Specific Rules + +| Language | Rule File | +|----------|-----------| +| **TypeScript/React** | `spacetimedb-typescript.mdc` (MANDATORY) | +| **Rust** | `spacetimedb-rust.mdc` (MANDATORY) | +| **C#** | `spacetimedb-csharp.mdc` (MANDATORY) | +| **Migrating 1.0 → 2.0** | `spacetimedb-migration-2.0.mdc` | + +--- + +## Core Concepts + +1. **Reducers are transactional** — they do not return data to callers +2. **Reducers must be deterministic** — no filesystem, network, timers, or random +3. **Read data via tables/subscriptions** — not reducer return values +4. **Auto-increment IDs are not sequential** — gaps are normal, don't use for ordering +5. **`ctx.sender` is the authenticated principal** — never trust identity args + +--- + +## Feature Implementation Checklist + +When implementing a feature that spans backend and client: + +1. **Backend:** Define table(s) to store the data +2. **Backend:** Define reducer(s) to mutate the data +3. **Client:** Subscribe to the table(s) +4. **Client:** Call the reducer(s) from UI — **don't forget this step!** +5. **Client:** Render the data from the table(s) + +**Common mistake:** Building backend tables/reducers but forgetting to wire up the client to call them. + +--- + +## Index System + +SpacetimeDB automatically creates indexes for: +- Primary key columns +- Columns marked as unique + +You can add explicit indexes on non-unique columns for query performance. + +**Index names must be unique across your entire module (all tables).** If two tables have indexes with the same declared name → conflict error. + +**Schema ↔ Code coupling:** +- Your query code references indexes by name +- If you add/remove/rename an index in the schema, update all code that uses it +- Removing an index without updating queries causes runtime errors + +--- + +## Commands + +```bash +# Login to allow remote database deployment e.g. to maincloud +spacetime login + +# Start local SpacetimeDB +spacetime start + +# Publish module +spacetime publish --module-path + +# Clear and republish +spacetime publish --clear-database -y --module-path + +# Generate client bindings +spacetime generate --lang --out-dir --module-path + +# View logs +spacetime logs +``` + +--- + +## Deployment + +- Maincloud is the spacetimedb hosted cloud and the default location for module publishing +- The default server marked by *** in `spacetime server list` should be used when publishing +- If the default server is maincloud you should publish to maincloud +- Publishing to maincloud is free of charge +- When publishing to maincloud the database dashboard will be at the url: https://spacetimedb.com/@/ +- The database owner can view utilization and performance metrics on the dashboard + +--- + +## Debugging Checklist + +1. Is SpacetimeDB server running? (`spacetime start`) +2. Is the module published? (`spacetime publish`) +3. Are client bindings generated? (`spacetime generate`) +4. Check server logs for errors (`spacetime logs `) +5. **Is the reducer actually being called from the client?** + +--- + +## Editing Behavior + +- Make the smallest change necessary +- Do NOT touch unrelated files, configs, or dependencies +- Do NOT invent new SpacetimeDB APIs — use only what exists in docs or this repo +- Do NOT add restrictions the prompt didn't ask for — if "users can do X", implement X for all users diff --git a/.env.local b/.env.local new file mode 100644 index 0000000..08915e6 --- /dev/null +++ b/.env.local @@ -0,0 +1,23 @@ +# Generic / backend +SPACETIMEDB_DB_NAME=my-spacetime-app-jdhdg +SPACETIMEDB_HOST=https://maincloud.spacetimedb.com + +# Vite +VITE_SPACETIMEDB_DB_NAME=my-spacetime-app-jdhdg +VITE_SPACETIMEDB_HOST=https://maincloud.spacetimedb.com + +# Next.js +NEXT_PUBLIC_SPACETIMEDB_DB_NAME=my-spacetime-app-jdhdg +NEXT_PUBLIC_SPACETIMEDB_HOST=https://maincloud.spacetimedb.com + +# Create React App +REACT_APP_SPACETIMEDB_DB_NAME=my-spacetime-app-jdhdg +REACT_APP_SPACETIMEDB_HOST=https://maincloud.spacetimedb.com + +# Expo +EXPO_PUBLIC_SPACETIMEDB_DB_NAME=my-spacetime-app-jdhdg +EXPO_PUBLIC_SPACETIMEDB_HOST=https://maincloud.spacetimedb.com + +# SvelteKit +PUBLIC_SPACETIMEDB_DB_NAME=my-spacetime-app-jdhdg +PUBLIC_SPACETIMEDB_HOST=https://maincloud.spacetimedb.com diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..c58f00b --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,766 @@ +# SpacetimeDB Rules (All Languages) + +## Migrating from 1.0 to 2.0? + +**If you are migrating existing SpacetimeDB 1.0 code to 2.0, apply `spacetimedb-migration-2.0.mdc` first.** It documents breaking changes (reducer callbacks → event tables, `name`→`accessor`, `sender()` method, etc.) and should be considered before other rules. + +--- + +## Language-Specific Rules + +| Language | Rule File | +|----------|-----------| +| **TypeScript/React** | `spacetimedb-typescript.mdc` (MANDATORY) | +| **Rust** | `spacetimedb-rust.mdc` (MANDATORY) | +| **C#** | `spacetimedb-csharp.mdc` (MANDATORY) | +| **Migrating 1.0 → 2.0** | `spacetimedb-migration-2.0.mdc` | + +--- + +## Core Concepts + +1. **Reducers are transactional** — they do not return data to callers +2. **Reducers must be deterministic** — no filesystem, network, timers, or random +3. **Read data via tables/subscriptions** — not reducer return values +4. **Auto-increment IDs are not sequential** — gaps are normal, don't use for ordering +5. **`ctx.sender` is the authenticated principal** — never trust identity args + +--- + +## Feature Implementation Checklist + +When implementing a feature that spans backend and client: + +1. **Backend:** Define table(s) to store the data +2. **Backend:** Define reducer(s) to mutate the data +3. **Client:** Subscribe to the table(s) +4. **Client:** Call the reducer(s) from UI — **don't forget this step!** +5. **Client:** Render the data from the table(s) + +**Common mistake:** Building backend tables/reducers but forgetting to wire up the client to call them. + +--- + +## Index System + +SpacetimeDB automatically creates indexes for: +- Primary key columns +- Columns marked as unique + +You can add explicit indexes on non-unique columns for query performance. + +**Index names must be unique across your entire module (all tables).** If two tables have indexes with the same declared name → conflict error. + +**Schema ↔ Code coupling:** +- Your query code references indexes by name +- If you add/remove/rename an index in the schema, update all code that uses it +- Removing an index without updating queries causes runtime errors + +--- + +## Commands + +```bash +# Login to allow remote database deployment e.g. to maincloud +spacetime login + +# Start local SpacetimeDB +spacetime start + +# Publish module +spacetime publish --module-path + +# Clear and republish +spacetime publish --clear-database -y --module-path + +# Generate client bindings +spacetime generate --lang --out-dir --module-path + +# View logs +spacetime logs +``` + +--- + +## Deployment + +- Maincloud is the spacetimedb hosted cloud and the default location for module publishing +- The default server marked by *** in `spacetime server list` should be used when publishing +- If the default server is maincloud you should publish to maincloud +- Publishing to maincloud is free of charge +- When publishing to maincloud the database dashboard will be at the url: https://spacetimedb.com/@/ +- The database owner can view utilization and performance metrics on the dashboard + +--- + +## Debugging Checklist + +1. Is SpacetimeDB server running? (`spacetime start`) +2. Is the module published? (`spacetime publish`) +3. Are client bindings generated? (`spacetime generate`) +4. Check server logs for errors (`spacetime logs `) +5. **Is the reducer actually being called from the client?** + +--- + +## Editing Behavior + +- Make the smallest change necessary +- Do NOT touch unrelated files, configs, or dependencies +- Do NOT invent new SpacetimeDB APIs — use only what exists in docs or this repo +- Do NOT add restrictions the prompt didn't ask for — if "users can do X", implement X for all users + + +# SpacetimeDB TypeScript SDK + +## ⛔ HALLUCINATED APIs — DO NOT USE + +**These APIs DO NOT EXIST. LLMs frequently hallucinate them.** + +```typescript +// ❌ WRONG PACKAGE — does not exist +import { SpacetimeDBClient } from "@clockworklabs/spacetimedb-sdk"; + +// ❌ WRONG — these methods don't exist +SpacetimeDBClient.connect(...); +SpacetimeDBClient.call("reducer_name", [...]); +connection.call("reducer_name", [arg1, arg2]); + +// ❌ WRONG — positional reducer arguments +conn.reducers.doSomething("value"); // WRONG! + +// ❌ WRONG — static methods on generated types don't exist +User.filterByName('alice'); +Message.findById(123n); +tables.user.filter(u => u.name === 'alice'); // No .filter() on tables object! +``` + +### ✅ CORRECT PATTERNS: + +```typescript +// ✅ CORRECT IMPORTS +import { DbConnection, tables } from './module_bindings'; // Generated! +import { SpacetimeDBProvider, useTable, Identity } from 'spacetimedb/react'; + +// ✅ CORRECT REDUCER CALLS — object syntax, not positional! +conn.reducers.doSomething({ value: 'test' }); +conn.reducers.updateItem({ itemId: 1n, newValue: 42 }); + +// ✅ CORRECT DATA ACCESS — useTable returns [rows, isLoading] +const [items, isLoading] = useTable(tables.item); +``` + +### ⛔ DO NOT: +- **Invent hooks** like `useItems()`, `useData()` — use `useTable(tables.tableName)` +- **Import from fake packages** — only `spacetimedb`, `spacetimedb/react`, `./module_bindings` + +--- + +## 1) Common Mistakes Table + +### Server-side errors + +| Wrong | Right | Error | +|-------|-------|-------| +| Missing `package.json` | Create `package.json` | "could not detect language" | +| Missing `tsconfig.json` | Create `tsconfig.json` | "TsconfigNotFound" | +| Entrypoint not at `src/index.ts` | Use `src/index.ts` | Module won't bundle | +| `indexes` in COLUMNS (2nd arg) | `indexes` in OPTIONS (1st arg) | "reading 'tag'" error | +| Index without `algorithm` | `algorithm: 'btree'` | "reading 'tag'" error | +| `filter({ ownerId })` | `filter(ownerId)` | "does not exist in type 'Range'" | +| `.filter()` on unique column | `.find()` on unique column | TypeError | +| `insert({ ...without id })` | `insert({ id: 0n, ... })` | "Property 'id' is missing" | +| `const id = table.insert(...)` | `const row = table.insert(...)` | `.insert()` returns ROW, not ID | +| `.unique()` + explicit index | Just use `.unique()` | "name is used for multiple entities" | +| Index on `.primaryKey()` column | Don't — already indexed | "name is used for multiple entities" | +| Same index name in multiple tables | Prefix with table name | "name is used for multiple entities" | +| `.indexName.filter()` after removing index | Use `.iter()` + manual filter | "Cannot read properties of undefined" | +| Import spacetimedb from index.ts | Import from schema.ts | "Cannot access before initialization" | +| Multi-column index `.filter()` | **⚠️ BROKEN** — use single-column | PANIC or silent empty results | +| `JSON.stringify({ id: row.id })` | Convert BigInt first: `{ id: row.id.toString() }` | "Do not know how to serialize a BigInt" | +| `ScheduleAt.Time(timestamp)` | `ScheduleAt.time(timestamp)` (lowercase) | "ScheduleAt.Time is not a function" | +| `ctx.db.foo.myIndexName.filter()` | Use exact name: `ctx.db.foo.my_index_name.filter()` | "Cannot read properties of undefined" | +| `.iter()` in views | Use index lookups | Severe performance issues (re-evaluates on any change) | +| `ctx.db` in procedures | `ctx.withTx(tx => tx.db...)` | Procedures need explicit transactions | +| `ctx.myTable` in procedure tx | `tx.db.myTable` | Wrong context variable | + +### Client-side errors + +| Wrong | Right | Error | +|-------|-------|-------| +| `@spacetimedb/sdk` | `spacetimedb` | 404 / missing subpath | +| `conn.reducers.foo("val")` | `conn.reducers.foo({ param: "val" })` | Wrong reducer syntax | +| Inline `connectionBuilder` | `useMemo(() => ..., [])` | Reconnects every render | +| `const rows = useTable(table)` | `const [rows, isLoading] = useTable(table)` | Tuple destructuring | +| Optimistic UI updates | Let subscriptions drive state | Desync issues | +| `` | `connectionBuilder={...}` | Wrong prop name | + +--- + +## 2) Table Definition (CRITICAL) + +**`table()` takes TWO arguments: `table(OPTIONS, COLUMNS)`** + +```typescript +import { schema, table, t } from 'spacetimedb/server'; + +// ❌ WRONG — indexes in COLUMNS causes "reading 'tag'" error +export const Task = table({ name: 'task' }, { + id: t.u64().primaryKey().autoInc(), + ownerId: t.identity(), + indexes: [{ name: 'by_owner', algorithm: 'btree', columns: ['ownerId'] }] // ❌ WRONG! +}); + +// ✅ RIGHT — indexes in OPTIONS (first argument) +export const Task = table({ + name: 'task', + public: true, + indexes: [{ name: 'by_owner', algorithm: 'btree', columns: ['ownerId'] }] +}, { + id: t.u64().primaryKey().autoInc(), + ownerId: t.identity(), + title: t.string(), + createdAt: t.timestamp(), +}); +``` + +### Column types +```typescript +t.identity() // User identity (primary key for per-user tables) +t.u64() // Unsigned 64-bit integer (use for IDs) +t.string() // Text +t.bool() // Boolean +t.timestamp() // Timestamp (use ctx.timestamp for current time) +t.scheduleAt() // For scheduled tables only + +// Product types (nested objects) — use t.object, NOT t.struct +const Point = t.object('Point', { x: t.i32(), y: t.i32() }); + +// Sum types (tagged unions) — use t.enum, NOT t.sum +const Shape = t.enum('Shape', { circle: t.i32(), rectangle: Point }); +// Values use { tag: 'circle', value: 10 } or { tag: 'rectangle', value: { x: 1, y: 2 } } + +// Modifiers +t.string().optional() // Nullable +t.u64().primaryKey() // Primary key +t.u64().primaryKey().autoInc() // Auto-increment primary key +``` + +> ⚠️ **BIGINT SYNTAX:** All `u64`, `i64`, and ID fields use JavaScript BigInt. +> - Literals: `0n`, `1n`, `100n` (NOT `0`, `1`, `100`) +> - Comparisons: `row.id === 5n` (NOT `row.id === 5`) +> - Arithmetic: `row.count + 1n` (NOT `row.count + 1`) + +### Auto-increment placeholder +```typescript +// ✅ MUST provide 0n placeholder for auto-inc fields +ctx.db.task.insert({ id: 0n, ownerId: ctx.sender, title: 'New', createdAt: ctx.timestamp }); +``` + +### Insert returns ROW, not ID +```typescript +// ❌ WRONG +const id = ctx.db.task.insert({ ... }); + +// ✅ RIGHT +const row = ctx.db.task.insert({ ... }); +const newId = row.id; // Extract .id from returned row +``` + +### Schema export (CRITICAL) +```typescript +// At end of schema.ts — schema() takes exactly ONE argument: an object +const spacetimedb = schema({ table1, table2, table3 }); +export default spacetimedb; + +// ❌ WRONG — never pass tables directly or as multiple args +schema(myTable); // WRONG! +schema(t1, t2, t3); // WRONG! +``` + +--- + +## 3) Index Access + +### TypeScript Query Patterns + +```typescript +// 1. PRIMARY KEY — use .pkColumn.find() +const user = ctx.db.user.identity.find(ctx.sender); +const msg = ctx.db.message.id.find(messageId); + +// 2. EXPLICIT INDEX — use .indexName.filter(value) +const msgs = [...ctx.db.message.message_room_id.filter(roomId)]; + +// 3. NO INDEX — use .iter() + manual filter +for (const m of ctx.db.roomMember.iter()) { + if (m.roomId === roomId) { /* ... */ } +} +``` + +### Index Definition Syntax + +```typescript +// In table OPTIONS (first argument), not columns +export const Message = table({ + name: 'message', + public: true, + indexes: [{ name: 'message_room_id', algorithm: 'btree', columns: ['roomId'] }] +}, { + id: t.u64().primaryKey().autoInc(), + roomId: t.u64(), + // ... +}); +``` + +### Naming conventions + +**Table names — automatic transformation:** +- Schema: `table({ name: 'my_messages' })` +- Access: `ctx.db.myMessages` (automatic snake_case → camelCase) + +**Index names — NO transformation, use EXACTLY as defined:** +```typescript +// Schema definition +indexes: [{ name: 'canvas_member_canvas_id', algorithm: 'btree', columns: ['canvasId'] }] + +// ❌ WRONG — don't assume camelCase transformation +ctx.db.canvasMember.canvasMember_canvas_id.filter(...) // WRONG! +ctx.db.canvasMember.canvasMemberCanvasId.filter(...) // WRONG! + +// ✅ RIGHT — use exact name from schema +ctx.db.canvasMember.canvas_member_canvas_id.filter(...) +``` + +> ⚠️ **Index names are used VERBATIM** — pick a convention (snake_case or camelCase) and stick with it. + +**Index naming pattern — use `{tableName}_{columnName}`:** +```typescript +// ✅ GOOD — unique names across entire module +indexes: [{ name: 'message_room_id', algorithm: 'btree', columns: ['roomId'] }] +indexes: [{ name: 'reaction_message_id', algorithm: 'btree', columns: ['messageId'] }] + +// ❌ BAD — will collide if multiple tables use same index name +indexes: [{ name: 'by_owner', ... }] // in Task table +indexes: [{ name: 'by_owner', ... }] // in Note table — CONFLICT! +``` + +**Client-side table names:** +- Check generated `module_bindings/index.ts` for exact export names +- Usage: `useTable(tables.MyMessages)` or `tables.myMessages` (varies by SDK version) + +### Filter vs Find +```typescript +// Filter takes VALUE directly, not object — returns iterator +const rows = [...ctx.db.task.by_owner.filter(ownerId)]; + +// Unique columns use .find() — returns single row or undefined +const row = ctx.db.player.identity.find(ctx.sender); +``` + +### ⚠️ Multi-column indexes are BROKEN +```typescript +// ❌ DON'T — causes PANIC +ctx.db.scores.by_player_level.filter(playerId); + +// ✅ DO — use single-column index + manual filter +for (const row of ctx.db.scores.by_player.filter(playerId)) { + if (row.level === targetLevel) { /* ... */ } +} +``` + +--- + +## 4) Reducers + +### Definition syntax (CRITICAL) +**Reducer name comes from the export — NOT from a string argument.** Use `reducer(params, fn)` or `reducer(fn)`. + +```typescript +import spacetimedb from './schema'; +import { t, SenderError } from 'spacetimedb/server'; + +// ✅ CORRECT — export const name = spacetimedb.reducer(params, fn) +export const reducer_name = spacetimedb.reducer({ param1: t.string(), param2: t.u64() }, (ctx, { param1, param2 }) => { + // Validation + if (!param1) throw new SenderError('param1 required'); + + // Access tables via ctx.db + const row = ctx.db.myTable.primaryKey.find(param2); + + // Mutations + ctx.db.myTable.insert({ ... }); + ctx.db.myTable.primaryKey.update({ ...row, newField: value }); + ctx.db.myTable.primaryKey.delete(param2); +}); + +// No params: export const init = spacetimedb.reducer((ctx) => { ... }); +``` + +```typescript +// ❌ WRONG — reducer('name', params, fn) does NOT exist +spacetimedb.reducer('reducer_name', { param1: t.string() }, (ctx, { param1 }) => { ... }); +``` + +### Update pattern (CRITICAL) +```typescript +// ✅ CORRECT — spread existing row, override specific fields +const existing = ctx.db.task.id.find(taskId); +if (!existing) throw new SenderError('Task not found'); +ctx.db.task.id.update({ ...existing, title: newTitle, updatedAt: ctx.timestamp }); + +// ❌ WRONG — partial update nulls out other fields! +ctx.db.task.id.update({ id: taskId, title: newTitle }); +``` + +### Delete pattern +```typescript +// Delete by primary key VALUE (not row object) +ctx.db.task.id.delete(taskId); // taskId is the u64 value +ctx.db.player.identity.delete(ctx.sender); // delete by identity +``` + +### Lifecycle hooks +```typescript +spacetimedb.clientConnected((ctx) => { + // ctx.sender is the connecting identity + // Create/update user record, set online status, etc. +}); + +spacetimedb.clientDisconnected((ctx) => { + // Clean up: set offline status, remove ephemeral data, etc. +}); +``` + +### Snake_case to camelCase conversion +- Server: `export const do_something = spacetimedb.reducer(...)` — name from export +- Client: `conn.reducers.doSomething({ ... })` + +### Object syntax required +```typescript +// ❌ WRONG - positional +conn.reducers.doSomething('value'); + +// ✅ RIGHT - object +conn.reducers.doSomething({ param: 'value' }); +``` + +--- + +## 5) Scheduled Tables + +```typescript +// 1. Define table first (scheduled: () => reducer — pass the exported reducer) +export const CleanupJob = table({ + name: 'cleanup_job', + scheduled: () => run_cleanup // reducer defined below +}, { + scheduledId: t.u64().primaryKey().autoInc(), + scheduledAt: t.scheduleAt(), + targetId: t.u64(), // Your custom data +}); + +// 2. Define scheduled reducer (receives full row as arg) +export const run_cleanup = spacetimedb.reducer({ arg: CleanupJob.rowType }, (ctx, { arg }) => { + // arg.scheduledId, arg.targetId available + // Row is auto-deleted after reducer completes +}); + +// Schedule a job +import { ScheduleAt } from 'spacetimedb'; +const futureTime = ctx.timestamp.microsSinceUnixEpoch + 60_000_000n; // 60 seconds +ctx.db.cleanupJob.insert({ + scheduledId: 0n, + scheduledAt: ScheduleAt.time(futureTime), + targetId: someId +}); + +// Cancel a job by deleting the row +ctx.db.cleanupJob.scheduledId.delete(jobId); +``` + +--- + +## 6) Timestamps + +### Server-side +```typescript +import { Timestamp, ScheduleAt } from 'spacetimedb'; + +// Current time +ctx.db.item.insert({ id: 0n, createdAt: ctx.timestamp }); + +// Future time (add microseconds) +const future = ctx.timestamp.microsSinceUnixEpoch + 300_000_000n; // 5 minutes +``` + +### Client-side (CRITICAL) +**Timestamps are objects, not numbers:** +```typescript +// ❌ WRONG +const date = new Date(row.createdAt); +const date = new Date(Number(row.createdAt / 1000n)); + +// ✅ RIGHT +const date = new Date(Number(row.createdAt.microsSinceUnixEpoch / 1000n)); +``` + +### ScheduleAt on client +```typescript +// ScheduleAt is a tagged union +if (scheduleAt.tag === 'Time') { + const date = new Date(Number(scheduleAt.value.microsSinceUnixEpoch / 1000n)); +} +``` + +--- + +## 7) Data Visibility & Subscriptions + +**`public: true` exposes ALL rows to ALL clients.** + +| Scenario | Pattern | +|----------|---------| +| Everyone sees all rows | `public: true` | +| Users see only their data | Private table + filtered subscription | + +### Subscription patterns (client-side) +```typescript +// Subscribe to ALL public tables (simplest) +conn.subscriptionBuilder().subscribeToAll(); + +// Subscribe to specific tables with SQL +conn.subscriptionBuilder().subscribe([ + 'SELECT * FROM message', + 'SELECT * FROM room WHERE is_public = true', +]); + +// Handle subscription lifecycle +conn.subscriptionBuilder() + .onApplied(() => console.log('Initial data loaded')) + .onError((e) => console.error('Subscription failed:', e)) + .subscribeToAll(); +``` + +### Private table + view pattern (RECOMMENDED) + +**Views are the recommended approach** for controlling data visibility. They provide: +- Server-side filtering (reduces network traffic) +- Real-time updates when underlying data changes +- Full control over what data clients can access + +> ⚠️ **Do NOT use Row Level Security (RLS)** — it is deprecated. + +> ⚠️ **CRITICAL:** Procedural views (views that compute results in code) can ONLY access data via index lookups, NOT `.iter()`. +> If you need a view that scans/filters across many rows (including the entire table), return a **query** built with the query builder (`ctx.from...`). + +```typescript +// Private table with index on ownerId +export const PrivateData = table( + { name: 'private_data', + indexes: [{ name: 'by_owner', algorithm: 'btree', columns: ['ownerId'] }] + }, + { + id: t.u64().primaryKey().autoInc(), + ownerId: t.identity(), + secret: t.string() + } +); + +// ❌ BAD — .iter() causes performance issues (re-evaluates on ANY row change) +spacetimedb.view( + { name: 'my_data_slow', public: true }, + t.array(PrivateData.rowType), + (ctx) => [...ctx.db.privateData.iter()] // Works but VERY slow at scale +); + +// ✅ GOOD — index lookup enables targeted invalidation +spacetimedb.view( + { name: 'my_data', public: true }, + t.array(PrivateData.rowType), + (ctx) => [...ctx.db.privateData.by_owner.filter(ctx.sender)] +); +``` + +### Query builder view pattern (can scan) + +```typescript +// Query-builder views return a query; the SQL engine maintains the result incrementally. +// This can scan the whole table if needed (e.g. leaderboard-style queries). +spacetimedb.anonymousView( + { name: 'top_players', public: true }, + t.array(Player.rowType), + (ctx) => + ctx.from.player + .where(p => p.score.gt(1000)) +); +``` + +### ViewContext vs AnonymousViewContext +```typescript +// ViewContext — has ctx.sender, result varies per user (computed per-subscriber) +spacetimedb.view({ name: 'my_items', public: true }, t.array(Item.rowType), (ctx) => { + return [...ctx.db.item.by_owner.filter(ctx.sender)]; +}); + +// AnonymousViewContext — no ctx.sender, same result for everyone (shared, better perf) +spacetimedb.anonymousView({ name: 'leaderboard', public: true }, t.array(LeaderboardRow), (ctx) => { + return [...ctx.db.player.by_score.filter(/* top scores */)]; +}); +``` + +**Views require explicit subscription:** +```typescript +conn.subscriptionBuilder().subscribe([ + 'SELECT * FROM public_table', + 'SELECT * FROM my_data', // Views need explicit SQL! +]); +``` + +--- + +## 8) React Integration + +### Key patterns +```typescript +// Memoize connectionBuilder to prevent reconnects on re-render +const builder = useMemo(() => + DbConnection.builder() + .withUri(SPACETIMEDB_URI) + .withDatabaseName(MODULE_NAME) + .withToken(localStorage.getItem('auth_token') || undefined) + .onConnect(onConnect) + .onConnectError(onConnectError), + [] // Empty deps - only create once +); + +// useTable returns tuple [rows, isLoading] +const [rows, isLoading] = useTable(tables.myTable); + +// Compare identities using toHexString() +const isOwner = row.ownerId.toHexString() === myIdentity.toHexString(); +``` + +--- + +## 9) Procedures (Beta) + +**Procedures are for side effects (HTTP requests, etc.) that reducers can't do.** + +⚠️ Procedures are currently in beta. API may change. + +### Defining a procedure +**Procedure name comes from the export — NOT from a string argument.** Use `procedure(params, ret, fn)` or `procedure(ret, fn)`. + +```typescript +// ✅ CORRECT — export const name = spacetimedb.procedure(params, ret, fn) +export const fetch_external_data = spacetimedb.procedure( + { url: t.string() }, + t.string(), // return type + (ctx, { url }) => { + const response = ctx.http.fetch(url); + return response.text(); + } +); +``` + +### Database access in procedures + +⚠️ **CRITICAL: Procedures don't have `ctx.db`. Use `ctx.withTx()` for database access.** + +```typescript +spacetimedb.procedure({ url: t.string() }, t.unit(), (ctx, { url }) => { + // Fetch external data (outside transaction) + const response = ctx.http.fetch(url); + const data = response.text(); + + // ❌ WRONG — ctx.db doesn't exist in procedures + ctx.db.myTable.insert({ ... }); + + // ✅ RIGHT — use ctx.withTx() for database access + ctx.withTx(tx => { + tx.db.myTable.insert({ + id: 0n, + content: data, + fetchedAt: tx.timestamp, + fetchedBy: tx.sender, + }); + }); + + return {}; +}); +``` + +### Key differences from reducers +| Reducers | Procedures | +|----------|------------| +| `ctx.db` available directly | Must use `ctx.withTx(tx => tx.db...)` | +| Automatic transaction | Manual transaction management | +| No HTTP/network | `ctx.http.fetch()` available | +| No return values to caller | Can return data to caller | + +--- + +## 10) Project Structure + +### Server (`backend/spacetimedb/`) +``` +src/schema.ts → Tables, export spacetimedb +src/index.ts → Reducers, lifecycle, import schema +package.json → { "type": "module", "dependencies": { "spacetimedb": "^1.11.0" } } +tsconfig.json → Standard config +``` + +### Avoiding circular imports +``` +schema.ts → defines tables AND exports spacetimedb +index.ts → imports spacetimedb from ./schema, defines reducers +``` + +### Client (`client/`) +``` +src/module_bindings/ → Generated (spacetime generate) +src/main.tsx → Provider, connection setup +src/App.tsx → UI components +src/config.ts → MODULE_NAME, SPACETIMEDB_URI +``` + +--- + +## 11) Commands + +```bash +# Start local server +spacetime start + +# Publish module +spacetime publish --module-path + +# Clear database and republish +spacetime publish --clear-database -y --module-path + +# Generate bindings +spacetime generate --lang typescript --out-dir /src/module_bindings --module-path + +# View logs +spacetime logs +``` + +--- + +## 12) Hard Requirements + +**TypeScript-specific:** + +1. **`schema({ table })`** — takes exactly one object; never `schema(table)` or `schema(t1, t2, t3)` +2. **Reducer/procedure names from exports** — `export const name = spacetimedb.reducer(params, fn)`; never `reducer('name', ...)` +3. **Reducer calls use object syntax** — `{ param: 'value' }` not positional args +4. **Import `DbConnection` from `./module_bindings`** — not from `spacetimedb` +5. **DO NOT edit generated bindings** — regenerate with `spacetime generate` +6. **Indexes go in OPTIONS (1st arg)** — not in COLUMNS (2nd arg) of `table()` +7. **Use BigInt for u64/i64 fields** — `0n`, `1n`, not `0`, `1` +8. **Reducers are transactional** — they do not return data +9. **Reducers must be deterministic** — no filesystem, network, timers, random +10. **Views should use index lookups** — `.iter()` causes severe performance issues +11. **Procedures need `ctx.withTx()`** — `ctx.db` doesn't exist in procedures +12. **Sum type values** — use `{ tag: 'variant', value: payload }` not `{ variant: payload }` diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..60090f2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Dependency directory +node_modules/ +jspm_packages/ + +# Build output +dist/ +out/ +build/ + +# IDEs and editors +.idea +.vscode/ +*.iml +*~ + +# Misc +.DS_Store +*.env.local +.env.development.local +.env.test.local +.env.production.local + +# Vite +.vite/ + +# SpacetimeDB build output +spacetimedb/dist/ + +# Ignore this file +.gitignore + diff --git a/.windsurfrules b/.windsurfrules new file mode 100644 index 0000000..c58f00b --- /dev/null +++ b/.windsurfrules @@ -0,0 +1,766 @@ +# SpacetimeDB Rules (All Languages) + +## Migrating from 1.0 to 2.0? + +**If you are migrating existing SpacetimeDB 1.0 code to 2.0, apply `spacetimedb-migration-2.0.mdc` first.** It documents breaking changes (reducer callbacks → event tables, `name`→`accessor`, `sender()` method, etc.) and should be considered before other rules. + +--- + +## Language-Specific Rules + +| Language | Rule File | +|----------|-----------| +| **TypeScript/React** | `spacetimedb-typescript.mdc` (MANDATORY) | +| **Rust** | `spacetimedb-rust.mdc` (MANDATORY) | +| **C#** | `spacetimedb-csharp.mdc` (MANDATORY) | +| **Migrating 1.0 → 2.0** | `spacetimedb-migration-2.0.mdc` | + +--- + +## Core Concepts + +1. **Reducers are transactional** — they do not return data to callers +2. **Reducers must be deterministic** — no filesystem, network, timers, or random +3. **Read data via tables/subscriptions** — not reducer return values +4. **Auto-increment IDs are not sequential** — gaps are normal, don't use for ordering +5. **`ctx.sender` is the authenticated principal** — never trust identity args + +--- + +## Feature Implementation Checklist + +When implementing a feature that spans backend and client: + +1. **Backend:** Define table(s) to store the data +2. **Backend:** Define reducer(s) to mutate the data +3. **Client:** Subscribe to the table(s) +4. **Client:** Call the reducer(s) from UI — **don't forget this step!** +5. **Client:** Render the data from the table(s) + +**Common mistake:** Building backend tables/reducers but forgetting to wire up the client to call them. + +--- + +## Index System + +SpacetimeDB automatically creates indexes for: +- Primary key columns +- Columns marked as unique + +You can add explicit indexes on non-unique columns for query performance. + +**Index names must be unique across your entire module (all tables).** If two tables have indexes with the same declared name → conflict error. + +**Schema ↔ Code coupling:** +- Your query code references indexes by name +- If you add/remove/rename an index in the schema, update all code that uses it +- Removing an index without updating queries causes runtime errors + +--- + +## Commands + +```bash +# Login to allow remote database deployment e.g. to maincloud +spacetime login + +# Start local SpacetimeDB +spacetime start + +# Publish module +spacetime publish --module-path + +# Clear and republish +spacetime publish --clear-database -y --module-path + +# Generate client bindings +spacetime generate --lang --out-dir --module-path + +# View logs +spacetime logs +``` + +--- + +## Deployment + +- Maincloud is the spacetimedb hosted cloud and the default location for module publishing +- The default server marked by *** in `spacetime server list` should be used when publishing +- If the default server is maincloud you should publish to maincloud +- Publishing to maincloud is free of charge +- When publishing to maincloud the database dashboard will be at the url: https://spacetimedb.com/@/ +- The database owner can view utilization and performance metrics on the dashboard + +--- + +## Debugging Checklist + +1. Is SpacetimeDB server running? (`spacetime start`) +2. Is the module published? (`spacetime publish`) +3. Are client bindings generated? (`spacetime generate`) +4. Check server logs for errors (`spacetime logs `) +5. **Is the reducer actually being called from the client?** + +--- + +## Editing Behavior + +- Make the smallest change necessary +- Do NOT touch unrelated files, configs, or dependencies +- Do NOT invent new SpacetimeDB APIs — use only what exists in docs or this repo +- Do NOT add restrictions the prompt didn't ask for — if "users can do X", implement X for all users + + +# SpacetimeDB TypeScript SDK + +## ⛔ HALLUCINATED APIs — DO NOT USE + +**These APIs DO NOT EXIST. LLMs frequently hallucinate them.** + +```typescript +// ❌ WRONG PACKAGE — does not exist +import { SpacetimeDBClient } from "@clockworklabs/spacetimedb-sdk"; + +// ❌ WRONG — these methods don't exist +SpacetimeDBClient.connect(...); +SpacetimeDBClient.call("reducer_name", [...]); +connection.call("reducer_name", [arg1, arg2]); + +// ❌ WRONG — positional reducer arguments +conn.reducers.doSomething("value"); // WRONG! + +// ❌ WRONG — static methods on generated types don't exist +User.filterByName('alice'); +Message.findById(123n); +tables.user.filter(u => u.name === 'alice'); // No .filter() on tables object! +``` + +### ✅ CORRECT PATTERNS: + +```typescript +// ✅ CORRECT IMPORTS +import { DbConnection, tables } from './module_bindings'; // Generated! +import { SpacetimeDBProvider, useTable, Identity } from 'spacetimedb/react'; + +// ✅ CORRECT REDUCER CALLS — object syntax, not positional! +conn.reducers.doSomething({ value: 'test' }); +conn.reducers.updateItem({ itemId: 1n, newValue: 42 }); + +// ✅ CORRECT DATA ACCESS — useTable returns [rows, isLoading] +const [items, isLoading] = useTable(tables.item); +``` + +### ⛔ DO NOT: +- **Invent hooks** like `useItems()`, `useData()` — use `useTable(tables.tableName)` +- **Import from fake packages** — only `spacetimedb`, `spacetimedb/react`, `./module_bindings` + +--- + +## 1) Common Mistakes Table + +### Server-side errors + +| Wrong | Right | Error | +|-------|-------|-------| +| Missing `package.json` | Create `package.json` | "could not detect language" | +| Missing `tsconfig.json` | Create `tsconfig.json` | "TsconfigNotFound" | +| Entrypoint not at `src/index.ts` | Use `src/index.ts` | Module won't bundle | +| `indexes` in COLUMNS (2nd arg) | `indexes` in OPTIONS (1st arg) | "reading 'tag'" error | +| Index without `algorithm` | `algorithm: 'btree'` | "reading 'tag'" error | +| `filter({ ownerId })` | `filter(ownerId)` | "does not exist in type 'Range'" | +| `.filter()` on unique column | `.find()` on unique column | TypeError | +| `insert({ ...without id })` | `insert({ id: 0n, ... })` | "Property 'id' is missing" | +| `const id = table.insert(...)` | `const row = table.insert(...)` | `.insert()` returns ROW, not ID | +| `.unique()` + explicit index | Just use `.unique()` | "name is used for multiple entities" | +| Index on `.primaryKey()` column | Don't — already indexed | "name is used for multiple entities" | +| Same index name in multiple tables | Prefix with table name | "name is used for multiple entities" | +| `.indexName.filter()` after removing index | Use `.iter()` + manual filter | "Cannot read properties of undefined" | +| Import spacetimedb from index.ts | Import from schema.ts | "Cannot access before initialization" | +| Multi-column index `.filter()` | **⚠️ BROKEN** — use single-column | PANIC or silent empty results | +| `JSON.stringify({ id: row.id })` | Convert BigInt first: `{ id: row.id.toString() }` | "Do not know how to serialize a BigInt" | +| `ScheduleAt.Time(timestamp)` | `ScheduleAt.time(timestamp)` (lowercase) | "ScheduleAt.Time is not a function" | +| `ctx.db.foo.myIndexName.filter()` | Use exact name: `ctx.db.foo.my_index_name.filter()` | "Cannot read properties of undefined" | +| `.iter()` in views | Use index lookups | Severe performance issues (re-evaluates on any change) | +| `ctx.db` in procedures | `ctx.withTx(tx => tx.db...)` | Procedures need explicit transactions | +| `ctx.myTable` in procedure tx | `tx.db.myTable` | Wrong context variable | + +### Client-side errors + +| Wrong | Right | Error | +|-------|-------|-------| +| `@spacetimedb/sdk` | `spacetimedb` | 404 / missing subpath | +| `conn.reducers.foo("val")` | `conn.reducers.foo({ param: "val" })` | Wrong reducer syntax | +| Inline `connectionBuilder` | `useMemo(() => ..., [])` | Reconnects every render | +| `const rows = useTable(table)` | `const [rows, isLoading] = useTable(table)` | Tuple destructuring | +| Optimistic UI updates | Let subscriptions drive state | Desync issues | +| `` | `connectionBuilder={...}` | Wrong prop name | + +--- + +## 2) Table Definition (CRITICAL) + +**`table()` takes TWO arguments: `table(OPTIONS, COLUMNS)`** + +```typescript +import { schema, table, t } from 'spacetimedb/server'; + +// ❌ WRONG — indexes in COLUMNS causes "reading 'tag'" error +export const Task = table({ name: 'task' }, { + id: t.u64().primaryKey().autoInc(), + ownerId: t.identity(), + indexes: [{ name: 'by_owner', algorithm: 'btree', columns: ['ownerId'] }] // ❌ WRONG! +}); + +// ✅ RIGHT — indexes in OPTIONS (first argument) +export const Task = table({ + name: 'task', + public: true, + indexes: [{ name: 'by_owner', algorithm: 'btree', columns: ['ownerId'] }] +}, { + id: t.u64().primaryKey().autoInc(), + ownerId: t.identity(), + title: t.string(), + createdAt: t.timestamp(), +}); +``` + +### Column types +```typescript +t.identity() // User identity (primary key for per-user tables) +t.u64() // Unsigned 64-bit integer (use for IDs) +t.string() // Text +t.bool() // Boolean +t.timestamp() // Timestamp (use ctx.timestamp for current time) +t.scheduleAt() // For scheduled tables only + +// Product types (nested objects) — use t.object, NOT t.struct +const Point = t.object('Point', { x: t.i32(), y: t.i32() }); + +// Sum types (tagged unions) — use t.enum, NOT t.sum +const Shape = t.enum('Shape', { circle: t.i32(), rectangle: Point }); +// Values use { tag: 'circle', value: 10 } or { tag: 'rectangle', value: { x: 1, y: 2 } } + +// Modifiers +t.string().optional() // Nullable +t.u64().primaryKey() // Primary key +t.u64().primaryKey().autoInc() // Auto-increment primary key +``` + +> ⚠️ **BIGINT SYNTAX:** All `u64`, `i64`, and ID fields use JavaScript BigInt. +> - Literals: `0n`, `1n`, `100n` (NOT `0`, `1`, `100`) +> - Comparisons: `row.id === 5n` (NOT `row.id === 5`) +> - Arithmetic: `row.count + 1n` (NOT `row.count + 1`) + +### Auto-increment placeholder +```typescript +// ✅ MUST provide 0n placeholder for auto-inc fields +ctx.db.task.insert({ id: 0n, ownerId: ctx.sender, title: 'New', createdAt: ctx.timestamp }); +``` + +### Insert returns ROW, not ID +```typescript +// ❌ WRONG +const id = ctx.db.task.insert({ ... }); + +// ✅ RIGHT +const row = ctx.db.task.insert({ ... }); +const newId = row.id; // Extract .id from returned row +``` + +### Schema export (CRITICAL) +```typescript +// At end of schema.ts — schema() takes exactly ONE argument: an object +const spacetimedb = schema({ table1, table2, table3 }); +export default spacetimedb; + +// ❌ WRONG — never pass tables directly or as multiple args +schema(myTable); // WRONG! +schema(t1, t2, t3); // WRONG! +``` + +--- + +## 3) Index Access + +### TypeScript Query Patterns + +```typescript +// 1. PRIMARY KEY — use .pkColumn.find() +const user = ctx.db.user.identity.find(ctx.sender); +const msg = ctx.db.message.id.find(messageId); + +// 2. EXPLICIT INDEX — use .indexName.filter(value) +const msgs = [...ctx.db.message.message_room_id.filter(roomId)]; + +// 3. NO INDEX — use .iter() + manual filter +for (const m of ctx.db.roomMember.iter()) { + if (m.roomId === roomId) { /* ... */ } +} +``` + +### Index Definition Syntax + +```typescript +// In table OPTIONS (first argument), not columns +export const Message = table({ + name: 'message', + public: true, + indexes: [{ name: 'message_room_id', algorithm: 'btree', columns: ['roomId'] }] +}, { + id: t.u64().primaryKey().autoInc(), + roomId: t.u64(), + // ... +}); +``` + +### Naming conventions + +**Table names — automatic transformation:** +- Schema: `table({ name: 'my_messages' })` +- Access: `ctx.db.myMessages` (automatic snake_case → camelCase) + +**Index names — NO transformation, use EXACTLY as defined:** +```typescript +// Schema definition +indexes: [{ name: 'canvas_member_canvas_id', algorithm: 'btree', columns: ['canvasId'] }] + +// ❌ WRONG — don't assume camelCase transformation +ctx.db.canvasMember.canvasMember_canvas_id.filter(...) // WRONG! +ctx.db.canvasMember.canvasMemberCanvasId.filter(...) // WRONG! + +// ✅ RIGHT — use exact name from schema +ctx.db.canvasMember.canvas_member_canvas_id.filter(...) +``` + +> ⚠️ **Index names are used VERBATIM** — pick a convention (snake_case or camelCase) and stick with it. + +**Index naming pattern — use `{tableName}_{columnName}`:** +```typescript +// ✅ GOOD — unique names across entire module +indexes: [{ name: 'message_room_id', algorithm: 'btree', columns: ['roomId'] }] +indexes: [{ name: 'reaction_message_id', algorithm: 'btree', columns: ['messageId'] }] + +// ❌ BAD — will collide if multiple tables use same index name +indexes: [{ name: 'by_owner', ... }] // in Task table +indexes: [{ name: 'by_owner', ... }] // in Note table — CONFLICT! +``` + +**Client-side table names:** +- Check generated `module_bindings/index.ts` for exact export names +- Usage: `useTable(tables.MyMessages)` or `tables.myMessages` (varies by SDK version) + +### Filter vs Find +```typescript +// Filter takes VALUE directly, not object — returns iterator +const rows = [...ctx.db.task.by_owner.filter(ownerId)]; + +// Unique columns use .find() — returns single row or undefined +const row = ctx.db.player.identity.find(ctx.sender); +``` + +### ⚠️ Multi-column indexes are BROKEN +```typescript +// ❌ DON'T — causes PANIC +ctx.db.scores.by_player_level.filter(playerId); + +// ✅ DO — use single-column index + manual filter +for (const row of ctx.db.scores.by_player.filter(playerId)) { + if (row.level === targetLevel) { /* ... */ } +} +``` + +--- + +## 4) Reducers + +### Definition syntax (CRITICAL) +**Reducer name comes from the export — NOT from a string argument.** Use `reducer(params, fn)` or `reducer(fn)`. + +```typescript +import spacetimedb from './schema'; +import { t, SenderError } from 'spacetimedb/server'; + +// ✅ CORRECT — export const name = spacetimedb.reducer(params, fn) +export const reducer_name = spacetimedb.reducer({ param1: t.string(), param2: t.u64() }, (ctx, { param1, param2 }) => { + // Validation + if (!param1) throw new SenderError('param1 required'); + + // Access tables via ctx.db + const row = ctx.db.myTable.primaryKey.find(param2); + + // Mutations + ctx.db.myTable.insert({ ... }); + ctx.db.myTable.primaryKey.update({ ...row, newField: value }); + ctx.db.myTable.primaryKey.delete(param2); +}); + +// No params: export const init = spacetimedb.reducer((ctx) => { ... }); +``` + +```typescript +// ❌ WRONG — reducer('name', params, fn) does NOT exist +spacetimedb.reducer('reducer_name', { param1: t.string() }, (ctx, { param1 }) => { ... }); +``` + +### Update pattern (CRITICAL) +```typescript +// ✅ CORRECT — spread existing row, override specific fields +const existing = ctx.db.task.id.find(taskId); +if (!existing) throw new SenderError('Task not found'); +ctx.db.task.id.update({ ...existing, title: newTitle, updatedAt: ctx.timestamp }); + +// ❌ WRONG — partial update nulls out other fields! +ctx.db.task.id.update({ id: taskId, title: newTitle }); +``` + +### Delete pattern +```typescript +// Delete by primary key VALUE (not row object) +ctx.db.task.id.delete(taskId); // taskId is the u64 value +ctx.db.player.identity.delete(ctx.sender); // delete by identity +``` + +### Lifecycle hooks +```typescript +spacetimedb.clientConnected((ctx) => { + // ctx.sender is the connecting identity + // Create/update user record, set online status, etc. +}); + +spacetimedb.clientDisconnected((ctx) => { + // Clean up: set offline status, remove ephemeral data, etc. +}); +``` + +### Snake_case to camelCase conversion +- Server: `export const do_something = spacetimedb.reducer(...)` — name from export +- Client: `conn.reducers.doSomething({ ... })` + +### Object syntax required +```typescript +// ❌ WRONG - positional +conn.reducers.doSomething('value'); + +// ✅ RIGHT - object +conn.reducers.doSomething({ param: 'value' }); +``` + +--- + +## 5) Scheduled Tables + +```typescript +// 1. Define table first (scheduled: () => reducer — pass the exported reducer) +export const CleanupJob = table({ + name: 'cleanup_job', + scheduled: () => run_cleanup // reducer defined below +}, { + scheduledId: t.u64().primaryKey().autoInc(), + scheduledAt: t.scheduleAt(), + targetId: t.u64(), // Your custom data +}); + +// 2. Define scheduled reducer (receives full row as arg) +export const run_cleanup = spacetimedb.reducer({ arg: CleanupJob.rowType }, (ctx, { arg }) => { + // arg.scheduledId, arg.targetId available + // Row is auto-deleted after reducer completes +}); + +// Schedule a job +import { ScheduleAt } from 'spacetimedb'; +const futureTime = ctx.timestamp.microsSinceUnixEpoch + 60_000_000n; // 60 seconds +ctx.db.cleanupJob.insert({ + scheduledId: 0n, + scheduledAt: ScheduleAt.time(futureTime), + targetId: someId +}); + +// Cancel a job by deleting the row +ctx.db.cleanupJob.scheduledId.delete(jobId); +``` + +--- + +## 6) Timestamps + +### Server-side +```typescript +import { Timestamp, ScheduleAt } from 'spacetimedb'; + +// Current time +ctx.db.item.insert({ id: 0n, createdAt: ctx.timestamp }); + +// Future time (add microseconds) +const future = ctx.timestamp.microsSinceUnixEpoch + 300_000_000n; // 5 minutes +``` + +### Client-side (CRITICAL) +**Timestamps are objects, not numbers:** +```typescript +// ❌ WRONG +const date = new Date(row.createdAt); +const date = new Date(Number(row.createdAt / 1000n)); + +// ✅ RIGHT +const date = new Date(Number(row.createdAt.microsSinceUnixEpoch / 1000n)); +``` + +### ScheduleAt on client +```typescript +// ScheduleAt is a tagged union +if (scheduleAt.tag === 'Time') { + const date = new Date(Number(scheduleAt.value.microsSinceUnixEpoch / 1000n)); +} +``` + +--- + +## 7) Data Visibility & Subscriptions + +**`public: true` exposes ALL rows to ALL clients.** + +| Scenario | Pattern | +|----------|---------| +| Everyone sees all rows | `public: true` | +| Users see only their data | Private table + filtered subscription | + +### Subscription patterns (client-side) +```typescript +// Subscribe to ALL public tables (simplest) +conn.subscriptionBuilder().subscribeToAll(); + +// Subscribe to specific tables with SQL +conn.subscriptionBuilder().subscribe([ + 'SELECT * FROM message', + 'SELECT * FROM room WHERE is_public = true', +]); + +// Handle subscription lifecycle +conn.subscriptionBuilder() + .onApplied(() => console.log('Initial data loaded')) + .onError((e) => console.error('Subscription failed:', e)) + .subscribeToAll(); +``` + +### Private table + view pattern (RECOMMENDED) + +**Views are the recommended approach** for controlling data visibility. They provide: +- Server-side filtering (reduces network traffic) +- Real-time updates when underlying data changes +- Full control over what data clients can access + +> ⚠️ **Do NOT use Row Level Security (RLS)** — it is deprecated. + +> ⚠️ **CRITICAL:** Procedural views (views that compute results in code) can ONLY access data via index lookups, NOT `.iter()`. +> If you need a view that scans/filters across many rows (including the entire table), return a **query** built with the query builder (`ctx.from...`). + +```typescript +// Private table with index on ownerId +export const PrivateData = table( + { name: 'private_data', + indexes: [{ name: 'by_owner', algorithm: 'btree', columns: ['ownerId'] }] + }, + { + id: t.u64().primaryKey().autoInc(), + ownerId: t.identity(), + secret: t.string() + } +); + +// ❌ BAD — .iter() causes performance issues (re-evaluates on ANY row change) +spacetimedb.view( + { name: 'my_data_slow', public: true }, + t.array(PrivateData.rowType), + (ctx) => [...ctx.db.privateData.iter()] // Works but VERY slow at scale +); + +// ✅ GOOD — index lookup enables targeted invalidation +spacetimedb.view( + { name: 'my_data', public: true }, + t.array(PrivateData.rowType), + (ctx) => [...ctx.db.privateData.by_owner.filter(ctx.sender)] +); +``` + +### Query builder view pattern (can scan) + +```typescript +// Query-builder views return a query; the SQL engine maintains the result incrementally. +// This can scan the whole table if needed (e.g. leaderboard-style queries). +spacetimedb.anonymousView( + { name: 'top_players', public: true }, + t.array(Player.rowType), + (ctx) => + ctx.from.player + .where(p => p.score.gt(1000)) +); +``` + +### ViewContext vs AnonymousViewContext +```typescript +// ViewContext — has ctx.sender, result varies per user (computed per-subscriber) +spacetimedb.view({ name: 'my_items', public: true }, t.array(Item.rowType), (ctx) => { + return [...ctx.db.item.by_owner.filter(ctx.sender)]; +}); + +// AnonymousViewContext — no ctx.sender, same result for everyone (shared, better perf) +spacetimedb.anonymousView({ name: 'leaderboard', public: true }, t.array(LeaderboardRow), (ctx) => { + return [...ctx.db.player.by_score.filter(/* top scores */)]; +}); +``` + +**Views require explicit subscription:** +```typescript +conn.subscriptionBuilder().subscribe([ + 'SELECT * FROM public_table', + 'SELECT * FROM my_data', // Views need explicit SQL! +]); +``` + +--- + +## 8) React Integration + +### Key patterns +```typescript +// Memoize connectionBuilder to prevent reconnects on re-render +const builder = useMemo(() => + DbConnection.builder() + .withUri(SPACETIMEDB_URI) + .withDatabaseName(MODULE_NAME) + .withToken(localStorage.getItem('auth_token') || undefined) + .onConnect(onConnect) + .onConnectError(onConnectError), + [] // Empty deps - only create once +); + +// useTable returns tuple [rows, isLoading] +const [rows, isLoading] = useTable(tables.myTable); + +// Compare identities using toHexString() +const isOwner = row.ownerId.toHexString() === myIdentity.toHexString(); +``` + +--- + +## 9) Procedures (Beta) + +**Procedures are for side effects (HTTP requests, etc.) that reducers can't do.** + +⚠️ Procedures are currently in beta. API may change. + +### Defining a procedure +**Procedure name comes from the export — NOT from a string argument.** Use `procedure(params, ret, fn)` or `procedure(ret, fn)`. + +```typescript +// ✅ CORRECT — export const name = spacetimedb.procedure(params, ret, fn) +export const fetch_external_data = spacetimedb.procedure( + { url: t.string() }, + t.string(), // return type + (ctx, { url }) => { + const response = ctx.http.fetch(url); + return response.text(); + } +); +``` + +### Database access in procedures + +⚠️ **CRITICAL: Procedures don't have `ctx.db`. Use `ctx.withTx()` for database access.** + +```typescript +spacetimedb.procedure({ url: t.string() }, t.unit(), (ctx, { url }) => { + // Fetch external data (outside transaction) + const response = ctx.http.fetch(url); + const data = response.text(); + + // ❌ WRONG — ctx.db doesn't exist in procedures + ctx.db.myTable.insert({ ... }); + + // ✅ RIGHT — use ctx.withTx() for database access + ctx.withTx(tx => { + tx.db.myTable.insert({ + id: 0n, + content: data, + fetchedAt: tx.timestamp, + fetchedBy: tx.sender, + }); + }); + + return {}; +}); +``` + +### Key differences from reducers +| Reducers | Procedures | +|----------|------------| +| `ctx.db` available directly | Must use `ctx.withTx(tx => tx.db...)` | +| Automatic transaction | Manual transaction management | +| No HTTP/network | `ctx.http.fetch()` available | +| No return values to caller | Can return data to caller | + +--- + +## 10) Project Structure + +### Server (`backend/spacetimedb/`) +``` +src/schema.ts → Tables, export spacetimedb +src/index.ts → Reducers, lifecycle, import schema +package.json → { "type": "module", "dependencies": { "spacetimedb": "^1.11.0" } } +tsconfig.json → Standard config +``` + +### Avoiding circular imports +``` +schema.ts → defines tables AND exports spacetimedb +index.ts → imports spacetimedb from ./schema, defines reducers +``` + +### Client (`client/`) +``` +src/module_bindings/ → Generated (spacetime generate) +src/main.tsx → Provider, connection setup +src/App.tsx → UI components +src/config.ts → MODULE_NAME, SPACETIMEDB_URI +``` + +--- + +## 11) Commands + +```bash +# Start local server +spacetime start + +# Publish module +spacetime publish --module-path + +# Clear database and republish +spacetime publish --clear-database -y --module-path + +# Generate bindings +spacetime generate --lang typescript --out-dir /src/module_bindings --module-path + +# View logs +spacetime logs +``` + +--- + +## 12) Hard Requirements + +**TypeScript-specific:** + +1. **`schema({ table })`** — takes exactly one object; never `schema(table)` or `schema(t1, t2, t3)` +2. **Reducer/procedure names from exports** — `export const name = spacetimedb.reducer(params, fn)`; never `reducer('name', ...)` +3. **Reducer calls use object syntax** — `{ param: 'value' }` not positional args +4. **Import `DbConnection` from `./module_bindings`** — not from `spacetimedb` +5. **DO NOT edit generated bindings** — regenerate with `spacetime generate` +6. **Indexes go in OPTIONS (1st arg)** — not in COLUMNS (2nd arg) of `table()` +7. **Use BigInt for u64/i64 fields** — `0n`, `1n`, not `0`, `1` +8. **Reducers are transactional** — they do not return data +9. **Reducers must be deterministic** — no filesystem, network, timers, random +10. **Views should use index lookups** — `.iter()` causes severe performance issues +11. **Procedures need `ctx.withTx()`** — `ctx.db` doesn't exist in procedures +12. **Sum type values** — use `{ tag: 'variant', value: payload }` not `{ variant: payload }` diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..c58f00b --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,766 @@ +# SpacetimeDB Rules (All Languages) + +## Migrating from 1.0 to 2.0? + +**If you are migrating existing SpacetimeDB 1.0 code to 2.0, apply `spacetimedb-migration-2.0.mdc` first.** It documents breaking changes (reducer callbacks → event tables, `name`→`accessor`, `sender()` method, etc.) and should be considered before other rules. + +--- + +## Language-Specific Rules + +| Language | Rule File | +|----------|-----------| +| **TypeScript/React** | `spacetimedb-typescript.mdc` (MANDATORY) | +| **Rust** | `spacetimedb-rust.mdc` (MANDATORY) | +| **C#** | `spacetimedb-csharp.mdc` (MANDATORY) | +| **Migrating 1.0 → 2.0** | `spacetimedb-migration-2.0.mdc` | + +--- + +## Core Concepts + +1. **Reducers are transactional** — they do not return data to callers +2. **Reducers must be deterministic** — no filesystem, network, timers, or random +3. **Read data via tables/subscriptions** — not reducer return values +4. **Auto-increment IDs are not sequential** — gaps are normal, don't use for ordering +5. **`ctx.sender` is the authenticated principal** — never trust identity args + +--- + +## Feature Implementation Checklist + +When implementing a feature that spans backend and client: + +1. **Backend:** Define table(s) to store the data +2. **Backend:** Define reducer(s) to mutate the data +3. **Client:** Subscribe to the table(s) +4. **Client:** Call the reducer(s) from UI — **don't forget this step!** +5. **Client:** Render the data from the table(s) + +**Common mistake:** Building backend tables/reducers but forgetting to wire up the client to call them. + +--- + +## Index System + +SpacetimeDB automatically creates indexes for: +- Primary key columns +- Columns marked as unique + +You can add explicit indexes on non-unique columns for query performance. + +**Index names must be unique across your entire module (all tables).** If two tables have indexes with the same declared name → conflict error. + +**Schema ↔ Code coupling:** +- Your query code references indexes by name +- If you add/remove/rename an index in the schema, update all code that uses it +- Removing an index without updating queries causes runtime errors + +--- + +## Commands + +```bash +# Login to allow remote database deployment e.g. to maincloud +spacetime login + +# Start local SpacetimeDB +spacetime start + +# Publish module +spacetime publish --module-path + +# Clear and republish +spacetime publish --clear-database -y --module-path + +# Generate client bindings +spacetime generate --lang --out-dir --module-path + +# View logs +spacetime logs +``` + +--- + +## Deployment + +- Maincloud is the spacetimedb hosted cloud and the default location for module publishing +- The default server marked by *** in `spacetime server list` should be used when publishing +- If the default server is maincloud you should publish to maincloud +- Publishing to maincloud is free of charge +- When publishing to maincloud the database dashboard will be at the url: https://spacetimedb.com/@/ +- The database owner can view utilization and performance metrics on the dashboard + +--- + +## Debugging Checklist + +1. Is SpacetimeDB server running? (`spacetime start`) +2. Is the module published? (`spacetime publish`) +3. Are client bindings generated? (`spacetime generate`) +4. Check server logs for errors (`spacetime logs `) +5. **Is the reducer actually being called from the client?** + +--- + +## Editing Behavior + +- Make the smallest change necessary +- Do NOT touch unrelated files, configs, or dependencies +- Do NOT invent new SpacetimeDB APIs — use only what exists in docs or this repo +- Do NOT add restrictions the prompt didn't ask for — if "users can do X", implement X for all users + + +# SpacetimeDB TypeScript SDK + +## ⛔ HALLUCINATED APIs — DO NOT USE + +**These APIs DO NOT EXIST. LLMs frequently hallucinate them.** + +```typescript +// ❌ WRONG PACKAGE — does not exist +import { SpacetimeDBClient } from "@clockworklabs/spacetimedb-sdk"; + +// ❌ WRONG — these methods don't exist +SpacetimeDBClient.connect(...); +SpacetimeDBClient.call("reducer_name", [...]); +connection.call("reducer_name", [arg1, arg2]); + +// ❌ WRONG — positional reducer arguments +conn.reducers.doSomething("value"); // WRONG! + +// ❌ WRONG — static methods on generated types don't exist +User.filterByName('alice'); +Message.findById(123n); +tables.user.filter(u => u.name === 'alice'); // No .filter() on tables object! +``` + +### ✅ CORRECT PATTERNS: + +```typescript +// ✅ CORRECT IMPORTS +import { DbConnection, tables } from './module_bindings'; // Generated! +import { SpacetimeDBProvider, useTable, Identity } from 'spacetimedb/react'; + +// ✅ CORRECT REDUCER CALLS — object syntax, not positional! +conn.reducers.doSomething({ value: 'test' }); +conn.reducers.updateItem({ itemId: 1n, newValue: 42 }); + +// ✅ CORRECT DATA ACCESS — useTable returns [rows, isLoading] +const [items, isLoading] = useTable(tables.item); +``` + +### ⛔ DO NOT: +- **Invent hooks** like `useItems()`, `useData()` — use `useTable(tables.tableName)` +- **Import from fake packages** — only `spacetimedb`, `spacetimedb/react`, `./module_bindings` + +--- + +## 1) Common Mistakes Table + +### Server-side errors + +| Wrong | Right | Error | +|-------|-------|-------| +| Missing `package.json` | Create `package.json` | "could not detect language" | +| Missing `tsconfig.json` | Create `tsconfig.json` | "TsconfigNotFound" | +| Entrypoint not at `src/index.ts` | Use `src/index.ts` | Module won't bundle | +| `indexes` in COLUMNS (2nd arg) | `indexes` in OPTIONS (1st arg) | "reading 'tag'" error | +| Index without `algorithm` | `algorithm: 'btree'` | "reading 'tag'" error | +| `filter({ ownerId })` | `filter(ownerId)` | "does not exist in type 'Range'" | +| `.filter()` on unique column | `.find()` on unique column | TypeError | +| `insert({ ...without id })` | `insert({ id: 0n, ... })` | "Property 'id' is missing" | +| `const id = table.insert(...)` | `const row = table.insert(...)` | `.insert()` returns ROW, not ID | +| `.unique()` + explicit index | Just use `.unique()` | "name is used for multiple entities" | +| Index on `.primaryKey()` column | Don't — already indexed | "name is used for multiple entities" | +| Same index name in multiple tables | Prefix with table name | "name is used for multiple entities" | +| `.indexName.filter()` after removing index | Use `.iter()` + manual filter | "Cannot read properties of undefined" | +| Import spacetimedb from index.ts | Import from schema.ts | "Cannot access before initialization" | +| Multi-column index `.filter()` | **⚠️ BROKEN** — use single-column | PANIC or silent empty results | +| `JSON.stringify({ id: row.id })` | Convert BigInt first: `{ id: row.id.toString() }` | "Do not know how to serialize a BigInt" | +| `ScheduleAt.Time(timestamp)` | `ScheduleAt.time(timestamp)` (lowercase) | "ScheduleAt.Time is not a function" | +| `ctx.db.foo.myIndexName.filter()` | Use exact name: `ctx.db.foo.my_index_name.filter()` | "Cannot read properties of undefined" | +| `.iter()` in views | Use index lookups | Severe performance issues (re-evaluates on any change) | +| `ctx.db` in procedures | `ctx.withTx(tx => tx.db...)` | Procedures need explicit transactions | +| `ctx.myTable` in procedure tx | `tx.db.myTable` | Wrong context variable | + +### Client-side errors + +| Wrong | Right | Error | +|-------|-------|-------| +| `@spacetimedb/sdk` | `spacetimedb` | 404 / missing subpath | +| `conn.reducers.foo("val")` | `conn.reducers.foo({ param: "val" })` | Wrong reducer syntax | +| Inline `connectionBuilder` | `useMemo(() => ..., [])` | Reconnects every render | +| `const rows = useTable(table)` | `const [rows, isLoading] = useTable(table)` | Tuple destructuring | +| Optimistic UI updates | Let subscriptions drive state | Desync issues | +| `` | `connectionBuilder={...}` | Wrong prop name | + +--- + +## 2) Table Definition (CRITICAL) + +**`table()` takes TWO arguments: `table(OPTIONS, COLUMNS)`** + +```typescript +import { schema, table, t } from 'spacetimedb/server'; + +// ❌ WRONG — indexes in COLUMNS causes "reading 'tag'" error +export const Task = table({ name: 'task' }, { + id: t.u64().primaryKey().autoInc(), + ownerId: t.identity(), + indexes: [{ name: 'by_owner', algorithm: 'btree', columns: ['ownerId'] }] // ❌ WRONG! +}); + +// ✅ RIGHT — indexes in OPTIONS (first argument) +export const Task = table({ + name: 'task', + public: true, + indexes: [{ name: 'by_owner', algorithm: 'btree', columns: ['ownerId'] }] +}, { + id: t.u64().primaryKey().autoInc(), + ownerId: t.identity(), + title: t.string(), + createdAt: t.timestamp(), +}); +``` + +### Column types +```typescript +t.identity() // User identity (primary key for per-user tables) +t.u64() // Unsigned 64-bit integer (use for IDs) +t.string() // Text +t.bool() // Boolean +t.timestamp() // Timestamp (use ctx.timestamp for current time) +t.scheduleAt() // For scheduled tables only + +// Product types (nested objects) — use t.object, NOT t.struct +const Point = t.object('Point', { x: t.i32(), y: t.i32() }); + +// Sum types (tagged unions) — use t.enum, NOT t.sum +const Shape = t.enum('Shape', { circle: t.i32(), rectangle: Point }); +// Values use { tag: 'circle', value: 10 } or { tag: 'rectangle', value: { x: 1, y: 2 } } + +// Modifiers +t.string().optional() // Nullable +t.u64().primaryKey() // Primary key +t.u64().primaryKey().autoInc() // Auto-increment primary key +``` + +> ⚠️ **BIGINT SYNTAX:** All `u64`, `i64`, and ID fields use JavaScript BigInt. +> - Literals: `0n`, `1n`, `100n` (NOT `0`, `1`, `100`) +> - Comparisons: `row.id === 5n` (NOT `row.id === 5`) +> - Arithmetic: `row.count + 1n` (NOT `row.count + 1`) + +### Auto-increment placeholder +```typescript +// ✅ MUST provide 0n placeholder for auto-inc fields +ctx.db.task.insert({ id: 0n, ownerId: ctx.sender, title: 'New', createdAt: ctx.timestamp }); +``` + +### Insert returns ROW, not ID +```typescript +// ❌ WRONG +const id = ctx.db.task.insert({ ... }); + +// ✅ RIGHT +const row = ctx.db.task.insert({ ... }); +const newId = row.id; // Extract .id from returned row +``` + +### Schema export (CRITICAL) +```typescript +// At end of schema.ts — schema() takes exactly ONE argument: an object +const spacetimedb = schema({ table1, table2, table3 }); +export default spacetimedb; + +// ❌ WRONG — never pass tables directly or as multiple args +schema(myTable); // WRONG! +schema(t1, t2, t3); // WRONG! +``` + +--- + +## 3) Index Access + +### TypeScript Query Patterns + +```typescript +// 1. PRIMARY KEY — use .pkColumn.find() +const user = ctx.db.user.identity.find(ctx.sender); +const msg = ctx.db.message.id.find(messageId); + +// 2. EXPLICIT INDEX — use .indexName.filter(value) +const msgs = [...ctx.db.message.message_room_id.filter(roomId)]; + +// 3. NO INDEX — use .iter() + manual filter +for (const m of ctx.db.roomMember.iter()) { + if (m.roomId === roomId) { /* ... */ } +} +``` + +### Index Definition Syntax + +```typescript +// In table OPTIONS (first argument), not columns +export const Message = table({ + name: 'message', + public: true, + indexes: [{ name: 'message_room_id', algorithm: 'btree', columns: ['roomId'] }] +}, { + id: t.u64().primaryKey().autoInc(), + roomId: t.u64(), + // ... +}); +``` + +### Naming conventions + +**Table names — automatic transformation:** +- Schema: `table({ name: 'my_messages' })` +- Access: `ctx.db.myMessages` (automatic snake_case → camelCase) + +**Index names — NO transformation, use EXACTLY as defined:** +```typescript +// Schema definition +indexes: [{ name: 'canvas_member_canvas_id', algorithm: 'btree', columns: ['canvasId'] }] + +// ❌ WRONG — don't assume camelCase transformation +ctx.db.canvasMember.canvasMember_canvas_id.filter(...) // WRONG! +ctx.db.canvasMember.canvasMemberCanvasId.filter(...) // WRONG! + +// ✅ RIGHT — use exact name from schema +ctx.db.canvasMember.canvas_member_canvas_id.filter(...) +``` + +> ⚠️ **Index names are used VERBATIM** — pick a convention (snake_case or camelCase) and stick with it. + +**Index naming pattern — use `{tableName}_{columnName}`:** +```typescript +// ✅ GOOD — unique names across entire module +indexes: [{ name: 'message_room_id', algorithm: 'btree', columns: ['roomId'] }] +indexes: [{ name: 'reaction_message_id', algorithm: 'btree', columns: ['messageId'] }] + +// ❌ BAD — will collide if multiple tables use same index name +indexes: [{ name: 'by_owner', ... }] // in Task table +indexes: [{ name: 'by_owner', ... }] // in Note table — CONFLICT! +``` + +**Client-side table names:** +- Check generated `module_bindings/index.ts` for exact export names +- Usage: `useTable(tables.MyMessages)` or `tables.myMessages` (varies by SDK version) + +### Filter vs Find +```typescript +// Filter takes VALUE directly, not object — returns iterator +const rows = [...ctx.db.task.by_owner.filter(ownerId)]; + +// Unique columns use .find() — returns single row or undefined +const row = ctx.db.player.identity.find(ctx.sender); +``` + +### ⚠️ Multi-column indexes are BROKEN +```typescript +// ❌ DON'T — causes PANIC +ctx.db.scores.by_player_level.filter(playerId); + +// ✅ DO — use single-column index + manual filter +for (const row of ctx.db.scores.by_player.filter(playerId)) { + if (row.level === targetLevel) { /* ... */ } +} +``` + +--- + +## 4) Reducers + +### Definition syntax (CRITICAL) +**Reducer name comes from the export — NOT from a string argument.** Use `reducer(params, fn)` or `reducer(fn)`. + +```typescript +import spacetimedb from './schema'; +import { t, SenderError } from 'spacetimedb/server'; + +// ✅ CORRECT — export const name = spacetimedb.reducer(params, fn) +export const reducer_name = spacetimedb.reducer({ param1: t.string(), param2: t.u64() }, (ctx, { param1, param2 }) => { + // Validation + if (!param1) throw new SenderError('param1 required'); + + // Access tables via ctx.db + const row = ctx.db.myTable.primaryKey.find(param2); + + // Mutations + ctx.db.myTable.insert({ ... }); + ctx.db.myTable.primaryKey.update({ ...row, newField: value }); + ctx.db.myTable.primaryKey.delete(param2); +}); + +// No params: export const init = spacetimedb.reducer((ctx) => { ... }); +``` + +```typescript +// ❌ WRONG — reducer('name', params, fn) does NOT exist +spacetimedb.reducer('reducer_name', { param1: t.string() }, (ctx, { param1 }) => { ... }); +``` + +### Update pattern (CRITICAL) +```typescript +// ✅ CORRECT — spread existing row, override specific fields +const existing = ctx.db.task.id.find(taskId); +if (!existing) throw new SenderError('Task not found'); +ctx.db.task.id.update({ ...existing, title: newTitle, updatedAt: ctx.timestamp }); + +// ❌ WRONG — partial update nulls out other fields! +ctx.db.task.id.update({ id: taskId, title: newTitle }); +``` + +### Delete pattern +```typescript +// Delete by primary key VALUE (not row object) +ctx.db.task.id.delete(taskId); // taskId is the u64 value +ctx.db.player.identity.delete(ctx.sender); // delete by identity +``` + +### Lifecycle hooks +```typescript +spacetimedb.clientConnected((ctx) => { + // ctx.sender is the connecting identity + // Create/update user record, set online status, etc. +}); + +spacetimedb.clientDisconnected((ctx) => { + // Clean up: set offline status, remove ephemeral data, etc. +}); +``` + +### Snake_case to camelCase conversion +- Server: `export const do_something = spacetimedb.reducer(...)` — name from export +- Client: `conn.reducers.doSomething({ ... })` + +### Object syntax required +```typescript +// ❌ WRONG - positional +conn.reducers.doSomething('value'); + +// ✅ RIGHT - object +conn.reducers.doSomething({ param: 'value' }); +``` + +--- + +## 5) Scheduled Tables + +```typescript +// 1. Define table first (scheduled: () => reducer — pass the exported reducer) +export const CleanupJob = table({ + name: 'cleanup_job', + scheduled: () => run_cleanup // reducer defined below +}, { + scheduledId: t.u64().primaryKey().autoInc(), + scheduledAt: t.scheduleAt(), + targetId: t.u64(), // Your custom data +}); + +// 2. Define scheduled reducer (receives full row as arg) +export const run_cleanup = spacetimedb.reducer({ arg: CleanupJob.rowType }, (ctx, { arg }) => { + // arg.scheduledId, arg.targetId available + // Row is auto-deleted after reducer completes +}); + +// Schedule a job +import { ScheduleAt } from 'spacetimedb'; +const futureTime = ctx.timestamp.microsSinceUnixEpoch + 60_000_000n; // 60 seconds +ctx.db.cleanupJob.insert({ + scheduledId: 0n, + scheduledAt: ScheduleAt.time(futureTime), + targetId: someId +}); + +// Cancel a job by deleting the row +ctx.db.cleanupJob.scheduledId.delete(jobId); +``` + +--- + +## 6) Timestamps + +### Server-side +```typescript +import { Timestamp, ScheduleAt } from 'spacetimedb'; + +// Current time +ctx.db.item.insert({ id: 0n, createdAt: ctx.timestamp }); + +// Future time (add microseconds) +const future = ctx.timestamp.microsSinceUnixEpoch + 300_000_000n; // 5 minutes +``` + +### Client-side (CRITICAL) +**Timestamps are objects, not numbers:** +```typescript +// ❌ WRONG +const date = new Date(row.createdAt); +const date = new Date(Number(row.createdAt / 1000n)); + +// ✅ RIGHT +const date = new Date(Number(row.createdAt.microsSinceUnixEpoch / 1000n)); +``` + +### ScheduleAt on client +```typescript +// ScheduleAt is a tagged union +if (scheduleAt.tag === 'Time') { + const date = new Date(Number(scheduleAt.value.microsSinceUnixEpoch / 1000n)); +} +``` + +--- + +## 7) Data Visibility & Subscriptions + +**`public: true` exposes ALL rows to ALL clients.** + +| Scenario | Pattern | +|----------|---------| +| Everyone sees all rows | `public: true` | +| Users see only their data | Private table + filtered subscription | + +### Subscription patterns (client-side) +```typescript +// Subscribe to ALL public tables (simplest) +conn.subscriptionBuilder().subscribeToAll(); + +// Subscribe to specific tables with SQL +conn.subscriptionBuilder().subscribe([ + 'SELECT * FROM message', + 'SELECT * FROM room WHERE is_public = true', +]); + +// Handle subscription lifecycle +conn.subscriptionBuilder() + .onApplied(() => console.log('Initial data loaded')) + .onError((e) => console.error('Subscription failed:', e)) + .subscribeToAll(); +``` + +### Private table + view pattern (RECOMMENDED) + +**Views are the recommended approach** for controlling data visibility. They provide: +- Server-side filtering (reduces network traffic) +- Real-time updates when underlying data changes +- Full control over what data clients can access + +> ⚠️ **Do NOT use Row Level Security (RLS)** — it is deprecated. + +> ⚠️ **CRITICAL:** Procedural views (views that compute results in code) can ONLY access data via index lookups, NOT `.iter()`. +> If you need a view that scans/filters across many rows (including the entire table), return a **query** built with the query builder (`ctx.from...`). + +```typescript +// Private table with index on ownerId +export const PrivateData = table( + { name: 'private_data', + indexes: [{ name: 'by_owner', algorithm: 'btree', columns: ['ownerId'] }] + }, + { + id: t.u64().primaryKey().autoInc(), + ownerId: t.identity(), + secret: t.string() + } +); + +// ❌ BAD — .iter() causes performance issues (re-evaluates on ANY row change) +spacetimedb.view( + { name: 'my_data_slow', public: true }, + t.array(PrivateData.rowType), + (ctx) => [...ctx.db.privateData.iter()] // Works but VERY slow at scale +); + +// ✅ GOOD — index lookup enables targeted invalidation +spacetimedb.view( + { name: 'my_data', public: true }, + t.array(PrivateData.rowType), + (ctx) => [...ctx.db.privateData.by_owner.filter(ctx.sender)] +); +``` + +### Query builder view pattern (can scan) + +```typescript +// Query-builder views return a query; the SQL engine maintains the result incrementally. +// This can scan the whole table if needed (e.g. leaderboard-style queries). +spacetimedb.anonymousView( + { name: 'top_players', public: true }, + t.array(Player.rowType), + (ctx) => + ctx.from.player + .where(p => p.score.gt(1000)) +); +``` + +### ViewContext vs AnonymousViewContext +```typescript +// ViewContext — has ctx.sender, result varies per user (computed per-subscriber) +spacetimedb.view({ name: 'my_items', public: true }, t.array(Item.rowType), (ctx) => { + return [...ctx.db.item.by_owner.filter(ctx.sender)]; +}); + +// AnonymousViewContext — no ctx.sender, same result for everyone (shared, better perf) +spacetimedb.anonymousView({ name: 'leaderboard', public: true }, t.array(LeaderboardRow), (ctx) => { + return [...ctx.db.player.by_score.filter(/* top scores */)]; +}); +``` + +**Views require explicit subscription:** +```typescript +conn.subscriptionBuilder().subscribe([ + 'SELECT * FROM public_table', + 'SELECT * FROM my_data', // Views need explicit SQL! +]); +``` + +--- + +## 8) React Integration + +### Key patterns +```typescript +// Memoize connectionBuilder to prevent reconnects on re-render +const builder = useMemo(() => + DbConnection.builder() + .withUri(SPACETIMEDB_URI) + .withDatabaseName(MODULE_NAME) + .withToken(localStorage.getItem('auth_token') || undefined) + .onConnect(onConnect) + .onConnectError(onConnectError), + [] // Empty deps - only create once +); + +// useTable returns tuple [rows, isLoading] +const [rows, isLoading] = useTable(tables.myTable); + +// Compare identities using toHexString() +const isOwner = row.ownerId.toHexString() === myIdentity.toHexString(); +``` + +--- + +## 9) Procedures (Beta) + +**Procedures are for side effects (HTTP requests, etc.) that reducers can't do.** + +⚠️ Procedures are currently in beta. API may change. + +### Defining a procedure +**Procedure name comes from the export — NOT from a string argument.** Use `procedure(params, ret, fn)` or `procedure(ret, fn)`. + +```typescript +// ✅ CORRECT — export const name = spacetimedb.procedure(params, ret, fn) +export const fetch_external_data = spacetimedb.procedure( + { url: t.string() }, + t.string(), // return type + (ctx, { url }) => { + const response = ctx.http.fetch(url); + return response.text(); + } +); +``` + +### Database access in procedures + +⚠️ **CRITICAL: Procedures don't have `ctx.db`. Use `ctx.withTx()` for database access.** + +```typescript +spacetimedb.procedure({ url: t.string() }, t.unit(), (ctx, { url }) => { + // Fetch external data (outside transaction) + const response = ctx.http.fetch(url); + const data = response.text(); + + // ❌ WRONG — ctx.db doesn't exist in procedures + ctx.db.myTable.insert({ ... }); + + // ✅ RIGHT — use ctx.withTx() for database access + ctx.withTx(tx => { + tx.db.myTable.insert({ + id: 0n, + content: data, + fetchedAt: tx.timestamp, + fetchedBy: tx.sender, + }); + }); + + return {}; +}); +``` + +### Key differences from reducers +| Reducers | Procedures | +|----------|------------| +| `ctx.db` available directly | Must use `ctx.withTx(tx => tx.db...)` | +| Automatic transaction | Manual transaction management | +| No HTTP/network | `ctx.http.fetch()` available | +| No return values to caller | Can return data to caller | + +--- + +## 10) Project Structure + +### Server (`backend/spacetimedb/`) +``` +src/schema.ts → Tables, export spacetimedb +src/index.ts → Reducers, lifecycle, import schema +package.json → { "type": "module", "dependencies": { "spacetimedb": "^1.11.0" } } +tsconfig.json → Standard config +``` + +### Avoiding circular imports +``` +schema.ts → defines tables AND exports spacetimedb +index.ts → imports spacetimedb from ./schema, defines reducers +``` + +### Client (`client/`) +``` +src/module_bindings/ → Generated (spacetime generate) +src/main.tsx → Provider, connection setup +src/App.tsx → UI components +src/config.ts → MODULE_NAME, SPACETIMEDB_URI +``` + +--- + +## 11) Commands + +```bash +# Start local server +spacetime start + +# Publish module +spacetime publish --module-path + +# Clear database and republish +spacetime publish --clear-database -y --module-path + +# Generate bindings +spacetime generate --lang typescript --out-dir /src/module_bindings --module-path + +# View logs +spacetime logs +``` + +--- + +## 12) Hard Requirements + +**TypeScript-specific:** + +1. **`schema({ table })`** — takes exactly one object; never `schema(table)` or `schema(t1, t2, t3)` +2. **Reducer/procedure names from exports** — `export const name = spacetimedb.reducer(params, fn)`; never `reducer('name', ...)` +3. **Reducer calls use object syntax** — `{ param: 'value' }` not positional args +4. **Import `DbConnection` from `./module_bindings`** — not from `spacetimedb` +5. **DO NOT edit generated bindings** — regenerate with `spacetime generate` +6. **Indexes go in OPTIONS (1st arg)** — not in COLUMNS (2nd arg) of `table()` +7. **Use BigInt for u64/i64 fields** — `0n`, `1n`, not `0`, `1` +8. **Reducers are transactional** — they do not return data +9. **Reducers must be deterministic** — no filesystem, network, timers, random +10. **Views should use index lookups** — `.iter()` causes severe performance issues +11. **Procedures need `ctx.withTx()`** — `ctx.db` doesn't exist in procedures +12. **Sum type values** — use `{ tag: 'variant', value: payload }` not `{ variant: payload }` diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..ecc61b6 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,29 @@ +# quickstart-chat + +## 0.0.1 + +### Patch Changes + +- Updated dependencies [[`cf7b7d8`](https://github.com/clockworklabs/spacetimedb-typescript-sdk/commit/cf7b7d89a1547fb3863f6641f5b2eb40a27c05d8), [`941cf4e`](https://github.com/clockworklabs/spacetimedb-typescript-sdk/commit/941cf4eba6b7df934d74696b373b89cc62764673), [`a501f5c`](https://github.com/clockworklabs/spacetimedb-typescript-sdk/commit/a501f5ccf9a0a926eb4f345ddeb01ffcb872d67e), [`9032269`](https://github.com/clockworklabs/spacetimedb-typescript-sdk/commit/9032269004d4dae587c39ccd85da0a32fb9a0114), [`6547882`](https://github.com/clockworklabs/spacetimedb-typescript-sdk/commit/6547882bb28ed9a1ca436335745e9997328026ff), [`5d7304b`](https://github.com/clockworklabs/spacetimedb-typescript-sdk/commit/5d7304bd3e05dd7a032cfb7069aab97b881f0179)]: + - @clockworklabs/spacetimedb-sdk@1.2.0 + +## 0.0.3-rc1.0 + +### Patch Changes + +- Updated dependencies [[`cf7b7d8`](https://github.com/clockworklabs/spacetimedb-typescript-sdk/commit/cf7b7d89a1547fb3863f6641f5b2eb40a27c05d8), [`a501f5c`](https://github.com/clockworklabs/spacetimedb-typescript-sdk/commit/a501f5ccf9a0a926eb4f345ddeb01ffcb872d67e), [`9032269`](https://github.com/clockworklabs/spacetimedb-typescript-sdk/commit/9032269004d4dae587c39ccd85da0a32fb9a0114), [`6547882`](https://github.com/clockworklabs/spacetimedb-typescript-sdk/commit/6547882bb28ed9a1ca436335745e9997328026ff), [`5d7304b`](https://github.com/clockworklabs/spacetimedb-typescript-sdk/commit/5d7304bd3e05dd7a032cfb7069aab97b881f0179)]: + - @clockworklabs/spacetimedb-sdk@1.0.0-rc1.0 + +## 0.0.2 + +### Patch Changes + +- Updated dependencies [[`2f6c82c`](https://github.com/clockworklabs/spacetimedb-typescript-sdk/commit/2f6c82c724b9f9407c7bedee13252ca8ffab8f7d), [`b9db9b6`](https://github.com/clockworklabs/spacetimedb-typescript-sdk/commit/b9db9b6e46d8c98b29327d97c12c07b7a2fc96bf), [`79c278b`](https://github.com/clockworklabs/spacetimedb-typescript-sdk/commit/79c278be71b2dfd82106ada983fd81d395b1d912)]: + - @clockworklabs/spacetimedb-sdk@0.12.1 + +## 0.0.1 + +### Patch Changes + +- Updated dependencies [[`5adb557`](https://github.com/clockworklabs/spacetimedb-typescript-sdk/commit/5adb55776c81d0760cf0268df0fa5dee600f0ef8), [`ab1f463`](https://github.com/clockworklabs/spacetimedb-typescript-sdk/commit/ab1f463d7da6e530a6cd47e2433141bfd16addd1), [`b8c944c`](https://github.com/clockworklabs/spacetimedb-typescript-sdk/commit/b8c944cd23d3b53c72131803a775127bf0a95213), [`17227c0`](https://github.com/clockworklabs/spacetimedb-typescript-sdk/commit/17227c0f65def3a9d5e767756ccf46777210041a)]: + - @clockworklabs/spacetimedb-sdk@0.12.0 diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..c58f00b --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,766 @@ +# SpacetimeDB Rules (All Languages) + +## Migrating from 1.0 to 2.0? + +**If you are migrating existing SpacetimeDB 1.0 code to 2.0, apply `spacetimedb-migration-2.0.mdc` first.** It documents breaking changes (reducer callbacks → event tables, `name`→`accessor`, `sender()` method, etc.) and should be considered before other rules. + +--- + +## Language-Specific Rules + +| Language | Rule File | +|----------|-----------| +| **TypeScript/React** | `spacetimedb-typescript.mdc` (MANDATORY) | +| **Rust** | `spacetimedb-rust.mdc` (MANDATORY) | +| **C#** | `spacetimedb-csharp.mdc` (MANDATORY) | +| **Migrating 1.0 → 2.0** | `spacetimedb-migration-2.0.mdc` | + +--- + +## Core Concepts + +1. **Reducers are transactional** — they do not return data to callers +2. **Reducers must be deterministic** — no filesystem, network, timers, or random +3. **Read data via tables/subscriptions** — not reducer return values +4. **Auto-increment IDs are not sequential** — gaps are normal, don't use for ordering +5. **`ctx.sender` is the authenticated principal** — never trust identity args + +--- + +## Feature Implementation Checklist + +When implementing a feature that spans backend and client: + +1. **Backend:** Define table(s) to store the data +2. **Backend:** Define reducer(s) to mutate the data +3. **Client:** Subscribe to the table(s) +4. **Client:** Call the reducer(s) from UI — **don't forget this step!** +5. **Client:** Render the data from the table(s) + +**Common mistake:** Building backend tables/reducers but forgetting to wire up the client to call them. + +--- + +## Index System + +SpacetimeDB automatically creates indexes for: +- Primary key columns +- Columns marked as unique + +You can add explicit indexes on non-unique columns for query performance. + +**Index names must be unique across your entire module (all tables).** If two tables have indexes with the same declared name → conflict error. + +**Schema ↔ Code coupling:** +- Your query code references indexes by name +- If you add/remove/rename an index in the schema, update all code that uses it +- Removing an index without updating queries causes runtime errors + +--- + +## Commands + +```bash +# Login to allow remote database deployment e.g. to maincloud +spacetime login + +# Start local SpacetimeDB +spacetime start + +# Publish module +spacetime publish --module-path + +# Clear and republish +spacetime publish --clear-database -y --module-path + +# Generate client bindings +spacetime generate --lang --out-dir --module-path + +# View logs +spacetime logs +``` + +--- + +## Deployment + +- Maincloud is the spacetimedb hosted cloud and the default location for module publishing +- The default server marked by *** in `spacetime server list` should be used when publishing +- If the default server is maincloud you should publish to maincloud +- Publishing to maincloud is free of charge +- When publishing to maincloud the database dashboard will be at the url: https://spacetimedb.com/@/ +- The database owner can view utilization and performance metrics on the dashboard + +--- + +## Debugging Checklist + +1. Is SpacetimeDB server running? (`spacetime start`) +2. Is the module published? (`spacetime publish`) +3. Are client bindings generated? (`spacetime generate`) +4. Check server logs for errors (`spacetime logs `) +5. **Is the reducer actually being called from the client?** + +--- + +## Editing Behavior + +- Make the smallest change necessary +- Do NOT touch unrelated files, configs, or dependencies +- Do NOT invent new SpacetimeDB APIs — use only what exists in docs or this repo +- Do NOT add restrictions the prompt didn't ask for — if "users can do X", implement X for all users + + +# SpacetimeDB TypeScript SDK + +## ⛔ HALLUCINATED APIs — DO NOT USE + +**These APIs DO NOT EXIST. LLMs frequently hallucinate them.** + +```typescript +// ❌ WRONG PACKAGE — does not exist +import { SpacetimeDBClient } from "@clockworklabs/spacetimedb-sdk"; + +// ❌ WRONG — these methods don't exist +SpacetimeDBClient.connect(...); +SpacetimeDBClient.call("reducer_name", [...]); +connection.call("reducer_name", [arg1, arg2]); + +// ❌ WRONG — positional reducer arguments +conn.reducers.doSomething("value"); // WRONG! + +// ❌ WRONG — static methods on generated types don't exist +User.filterByName('alice'); +Message.findById(123n); +tables.user.filter(u => u.name === 'alice'); // No .filter() on tables object! +``` + +### ✅ CORRECT PATTERNS: + +```typescript +// ✅ CORRECT IMPORTS +import { DbConnection, tables } from './module_bindings'; // Generated! +import { SpacetimeDBProvider, useTable, Identity } from 'spacetimedb/react'; + +// ✅ CORRECT REDUCER CALLS — object syntax, not positional! +conn.reducers.doSomething({ value: 'test' }); +conn.reducers.updateItem({ itemId: 1n, newValue: 42 }); + +// ✅ CORRECT DATA ACCESS — useTable returns [rows, isLoading] +const [items, isLoading] = useTable(tables.item); +``` + +### ⛔ DO NOT: +- **Invent hooks** like `useItems()`, `useData()` — use `useTable(tables.tableName)` +- **Import from fake packages** — only `spacetimedb`, `spacetimedb/react`, `./module_bindings` + +--- + +## 1) Common Mistakes Table + +### Server-side errors + +| Wrong | Right | Error | +|-------|-------|-------| +| Missing `package.json` | Create `package.json` | "could not detect language" | +| Missing `tsconfig.json` | Create `tsconfig.json` | "TsconfigNotFound" | +| Entrypoint not at `src/index.ts` | Use `src/index.ts` | Module won't bundle | +| `indexes` in COLUMNS (2nd arg) | `indexes` in OPTIONS (1st arg) | "reading 'tag'" error | +| Index without `algorithm` | `algorithm: 'btree'` | "reading 'tag'" error | +| `filter({ ownerId })` | `filter(ownerId)` | "does not exist in type 'Range'" | +| `.filter()` on unique column | `.find()` on unique column | TypeError | +| `insert({ ...without id })` | `insert({ id: 0n, ... })` | "Property 'id' is missing" | +| `const id = table.insert(...)` | `const row = table.insert(...)` | `.insert()` returns ROW, not ID | +| `.unique()` + explicit index | Just use `.unique()` | "name is used for multiple entities" | +| Index on `.primaryKey()` column | Don't — already indexed | "name is used for multiple entities" | +| Same index name in multiple tables | Prefix with table name | "name is used for multiple entities" | +| `.indexName.filter()` after removing index | Use `.iter()` + manual filter | "Cannot read properties of undefined" | +| Import spacetimedb from index.ts | Import from schema.ts | "Cannot access before initialization" | +| Multi-column index `.filter()` | **⚠️ BROKEN** — use single-column | PANIC or silent empty results | +| `JSON.stringify({ id: row.id })` | Convert BigInt first: `{ id: row.id.toString() }` | "Do not know how to serialize a BigInt" | +| `ScheduleAt.Time(timestamp)` | `ScheduleAt.time(timestamp)` (lowercase) | "ScheduleAt.Time is not a function" | +| `ctx.db.foo.myIndexName.filter()` | Use exact name: `ctx.db.foo.my_index_name.filter()` | "Cannot read properties of undefined" | +| `.iter()` in views | Use index lookups | Severe performance issues (re-evaluates on any change) | +| `ctx.db` in procedures | `ctx.withTx(tx => tx.db...)` | Procedures need explicit transactions | +| `ctx.myTable` in procedure tx | `tx.db.myTable` | Wrong context variable | + +### Client-side errors + +| Wrong | Right | Error | +|-------|-------|-------| +| `@spacetimedb/sdk` | `spacetimedb` | 404 / missing subpath | +| `conn.reducers.foo("val")` | `conn.reducers.foo({ param: "val" })` | Wrong reducer syntax | +| Inline `connectionBuilder` | `useMemo(() => ..., [])` | Reconnects every render | +| `const rows = useTable(table)` | `const [rows, isLoading] = useTable(table)` | Tuple destructuring | +| Optimistic UI updates | Let subscriptions drive state | Desync issues | +| `` | `connectionBuilder={...}` | Wrong prop name | + +--- + +## 2) Table Definition (CRITICAL) + +**`table()` takes TWO arguments: `table(OPTIONS, COLUMNS)`** + +```typescript +import { schema, table, t } from 'spacetimedb/server'; + +// ❌ WRONG — indexes in COLUMNS causes "reading 'tag'" error +export const Task = table({ name: 'task' }, { + id: t.u64().primaryKey().autoInc(), + ownerId: t.identity(), + indexes: [{ name: 'by_owner', algorithm: 'btree', columns: ['ownerId'] }] // ❌ WRONG! +}); + +// ✅ RIGHT — indexes in OPTIONS (first argument) +export const Task = table({ + name: 'task', + public: true, + indexes: [{ name: 'by_owner', algorithm: 'btree', columns: ['ownerId'] }] +}, { + id: t.u64().primaryKey().autoInc(), + ownerId: t.identity(), + title: t.string(), + createdAt: t.timestamp(), +}); +``` + +### Column types +```typescript +t.identity() // User identity (primary key for per-user tables) +t.u64() // Unsigned 64-bit integer (use for IDs) +t.string() // Text +t.bool() // Boolean +t.timestamp() // Timestamp (use ctx.timestamp for current time) +t.scheduleAt() // For scheduled tables only + +// Product types (nested objects) — use t.object, NOT t.struct +const Point = t.object('Point', { x: t.i32(), y: t.i32() }); + +// Sum types (tagged unions) — use t.enum, NOT t.sum +const Shape = t.enum('Shape', { circle: t.i32(), rectangle: Point }); +// Values use { tag: 'circle', value: 10 } or { tag: 'rectangle', value: { x: 1, y: 2 } } + +// Modifiers +t.string().optional() // Nullable +t.u64().primaryKey() // Primary key +t.u64().primaryKey().autoInc() // Auto-increment primary key +``` + +> ⚠️ **BIGINT SYNTAX:** All `u64`, `i64`, and ID fields use JavaScript BigInt. +> - Literals: `0n`, `1n`, `100n` (NOT `0`, `1`, `100`) +> - Comparisons: `row.id === 5n` (NOT `row.id === 5`) +> - Arithmetic: `row.count + 1n` (NOT `row.count + 1`) + +### Auto-increment placeholder +```typescript +// ✅ MUST provide 0n placeholder for auto-inc fields +ctx.db.task.insert({ id: 0n, ownerId: ctx.sender, title: 'New', createdAt: ctx.timestamp }); +``` + +### Insert returns ROW, not ID +```typescript +// ❌ WRONG +const id = ctx.db.task.insert({ ... }); + +// ✅ RIGHT +const row = ctx.db.task.insert({ ... }); +const newId = row.id; // Extract .id from returned row +``` + +### Schema export (CRITICAL) +```typescript +// At end of schema.ts — schema() takes exactly ONE argument: an object +const spacetimedb = schema({ table1, table2, table3 }); +export default spacetimedb; + +// ❌ WRONG — never pass tables directly or as multiple args +schema(myTable); // WRONG! +schema(t1, t2, t3); // WRONG! +``` + +--- + +## 3) Index Access + +### TypeScript Query Patterns + +```typescript +// 1. PRIMARY KEY — use .pkColumn.find() +const user = ctx.db.user.identity.find(ctx.sender); +const msg = ctx.db.message.id.find(messageId); + +// 2. EXPLICIT INDEX — use .indexName.filter(value) +const msgs = [...ctx.db.message.message_room_id.filter(roomId)]; + +// 3. NO INDEX — use .iter() + manual filter +for (const m of ctx.db.roomMember.iter()) { + if (m.roomId === roomId) { /* ... */ } +} +``` + +### Index Definition Syntax + +```typescript +// In table OPTIONS (first argument), not columns +export const Message = table({ + name: 'message', + public: true, + indexes: [{ name: 'message_room_id', algorithm: 'btree', columns: ['roomId'] }] +}, { + id: t.u64().primaryKey().autoInc(), + roomId: t.u64(), + // ... +}); +``` + +### Naming conventions + +**Table names — automatic transformation:** +- Schema: `table({ name: 'my_messages' })` +- Access: `ctx.db.myMessages` (automatic snake_case → camelCase) + +**Index names — NO transformation, use EXACTLY as defined:** +```typescript +// Schema definition +indexes: [{ name: 'canvas_member_canvas_id', algorithm: 'btree', columns: ['canvasId'] }] + +// ❌ WRONG — don't assume camelCase transformation +ctx.db.canvasMember.canvasMember_canvas_id.filter(...) // WRONG! +ctx.db.canvasMember.canvasMemberCanvasId.filter(...) // WRONG! + +// ✅ RIGHT — use exact name from schema +ctx.db.canvasMember.canvas_member_canvas_id.filter(...) +``` + +> ⚠️ **Index names are used VERBATIM** — pick a convention (snake_case or camelCase) and stick with it. + +**Index naming pattern — use `{tableName}_{columnName}`:** +```typescript +// ✅ GOOD — unique names across entire module +indexes: [{ name: 'message_room_id', algorithm: 'btree', columns: ['roomId'] }] +indexes: [{ name: 'reaction_message_id', algorithm: 'btree', columns: ['messageId'] }] + +// ❌ BAD — will collide if multiple tables use same index name +indexes: [{ name: 'by_owner', ... }] // in Task table +indexes: [{ name: 'by_owner', ... }] // in Note table — CONFLICT! +``` + +**Client-side table names:** +- Check generated `module_bindings/index.ts` for exact export names +- Usage: `useTable(tables.MyMessages)` or `tables.myMessages` (varies by SDK version) + +### Filter vs Find +```typescript +// Filter takes VALUE directly, not object — returns iterator +const rows = [...ctx.db.task.by_owner.filter(ownerId)]; + +// Unique columns use .find() — returns single row or undefined +const row = ctx.db.player.identity.find(ctx.sender); +``` + +### ⚠️ Multi-column indexes are BROKEN +```typescript +// ❌ DON'T — causes PANIC +ctx.db.scores.by_player_level.filter(playerId); + +// ✅ DO — use single-column index + manual filter +for (const row of ctx.db.scores.by_player.filter(playerId)) { + if (row.level === targetLevel) { /* ... */ } +} +``` + +--- + +## 4) Reducers + +### Definition syntax (CRITICAL) +**Reducer name comes from the export — NOT from a string argument.** Use `reducer(params, fn)` or `reducer(fn)`. + +```typescript +import spacetimedb from './schema'; +import { t, SenderError } from 'spacetimedb/server'; + +// ✅ CORRECT — export const name = spacetimedb.reducer(params, fn) +export const reducer_name = spacetimedb.reducer({ param1: t.string(), param2: t.u64() }, (ctx, { param1, param2 }) => { + // Validation + if (!param1) throw new SenderError('param1 required'); + + // Access tables via ctx.db + const row = ctx.db.myTable.primaryKey.find(param2); + + // Mutations + ctx.db.myTable.insert({ ... }); + ctx.db.myTable.primaryKey.update({ ...row, newField: value }); + ctx.db.myTable.primaryKey.delete(param2); +}); + +// No params: export const init = spacetimedb.reducer((ctx) => { ... }); +``` + +```typescript +// ❌ WRONG — reducer('name', params, fn) does NOT exist +spacetimedb.reducer('reducer_name', { param1: t.string() }, (ctx, { param1 }) => { ... }); +``` + +### Update pattern (CRITICAL) +```typescript +// ✅ CORRECT — spread existing row, override specific fields +const existing = ctx.db.task.id.find(taskId); +if (!existing) throw new SenderError('Task not found'); +ctx.db.task.id.update({ ...existing, title: newTitle, updatedAt: ctx.timestamp }); + +// ❌ WRONG — partial update nulls out other fields! +ctx.db.task.id.update({ id: taskId, title: newTitle }); +``` + +### Delete pattern +```typescript +// Delete by primary key VALUE (not row object) +ctx.db.task.id.delete(taskId); // taskId is the u64 value +ctx.db.player.identity.delete(ctx.sender); // delete by identity +``` + +### Lifecycle hooks +```typescript +spacetimedb.clientConnected((ctx) => { + // ctx.sender is the connecting identity + // Create/update user record, set online status, etc. +}); + +spacetimedb.clientDisconnected((ctx) => { + // Clean up: set offline status, remove ephemeral data, etc. +}); +``` + +### Snake_case to camelCase conversion +- Server: `export const do_something = spacetimedb.reducer(...)` — name from export +- Client: `conn.reducers.doSomething({ ... })` + +### Object syntax required +```typescript +// ❌ WRONG - positional +conn.reducers.doSomething('value'); + +// ✅ RIGHT - object +conn.reducers.doSomething({ param: 'value' }); +``` + +--- + +## 5) Scheduled Tables + +```typescript +// 1. Define table first (scheduled: () => reducer — pass the exported reducer) +export const CleanupJob = table({ + name: 'cleanup_job', + scheduled: () => run_cleanup // reducer defined below +}, { + scheduledId: t.u64().primaryKey().autoInc(), + scheduledAt: t.scheduleAt(), + targetId: t.u64(), // Your custom data +}); + +// 2. Define scheduled reducer (receives full row as arg) +export const run_cleanup = spacetimedb.reducer({ arg: CleanupJob.rowType }, (ctx, { arg }) => { + // arg.scheduledId, arg.targetId available + // Row is auto-deleted after reducer completes +}); + +// Schedule a job +import { ScheduleAt } from 'spacetimedb'; +const futureTime = ctx.timestamp.microsSinceUnixEpoch + 60_000_000n; // 60 seconds +ctx.db.cleanupJob.insert({ + scheduledId: 0n, + scheduledAt: ScheduleAt.time(futureTime), + targetId: someId +}); + +// Cancel a job by deleting the row +ctx.db.cleanupJob.scheduledId.delete(jobId); +``` + +--- + +## 6) Timestamps + +### Server-side +```typescript +import { Timestamp, ScheduleAt } from 'spacetimedb'; + +// Current time +ctx.db.item.insert({ id: 0n, createdAt: ctx.timestamp }); + +// Future time (add microseconds) +const future = ctx.timestamp.microsSinceUnixEpoch + 300_000_000n; // 5 minutes +``` + +### Client-side (CRITICAL) +**Timestamps are objects, not numbers:** +```typescript +// ❌ WRONG +const date = new Date(row.createdAt); +const date = new Date(Number(row.createdAt / 1000n)); + +// ✅ RIGHT +const date = new Date(Number(row.createdAt.microsSinceUnixEpoch / 1000n)); +``` + +### ScheduleAt on client +```typescript +// ScheduleAt is a tagged union +if (scheduleAt.tag === 'Time') { + const date = new Date(Number(scheduleAt.value.microsSinceUnixEpoch / 1000n)); +} +``` + +--- + +## 7) Data Visibility & Subscriptions + +**`public: true` exposes ALL rows to ALL clients.** + +| Scenario | Pattern | +|----------|---------| +| Everyone sees all rows | `public: true` | +| Users see only their data | Private table + filtered subscription | + +### Subscription patterns (client-side) +```typescript +// Subscribe to ALL public tables (simplest) +conn.subscriptionBuilder().subscribeToAll(); + +// Subscribe to specific tables with SQL +conn.subscriptionBuilder().subscribe([ + 'SELECT * FROM message', + 'SELECT * FROM room WHERE is_public = true', +]); + +// Handle subscription lifecycle +conn.subscriptionBuilder() + .onApplied(() => console.log('Initial data loaded')) + .onError((e) => console.error('Subscription failed:', e)) + .subscribeToAll(); +``` + +### Private table + view pattern (RECOMMENDED) + +**Views are the recommended approach** for controlling data visibility. They provide: +- Server-side filtering (reduces network traffic) +- Real-time updates when underlying data changes +- Full control over what data clients can access + +> ⚠️ **Do NOT use Row Level Security (RLS)** — it is deprecated. + +> ⚠️ **CRITICAL:** Procedural views (views that compute results in code) can ONLY access data via index lookups, NOT `.iter()`. +> If you need a view that scans/filters across many rows (including the entire table), return a **query** built with the query builder (`ctx.from...`). + +```typescript +// Private table with index on ownerId +export const PrivateData = table( + { name: 'private_data', + indexes: [{ name: 'by_owner', algorithm: 'btree', columns: ['ownerId'] }] + }, + { + id: t.u64().primaryKey().autoInc(), + ownerId: t.identity(), + secret: t.string() + } +); + +// ❌ BAD — .iter() causes performance issues (re-evaluates on ANY row change) +spacetimedb.view( + { name: 'my_data_slow', public: true }, + t.array(PrivateData.rowType), + (ctx) => [...ctx.db.privateData.iter()] // Works but VERY slow at scale +); + +// ✅ GOOD — index lookup enables targeted invalidation +spacetimedb.view( + { name: 'my_data', public: true }, + t.array(PrivateData.rowType), + (ctx) => [...ctx.db.privateData.by_owner.filter(ctx.sender)] +); +``` + +### Query builder view pattern (can scan) + +```typescript +// Query-builder views return a query; the SQL engine maintains the result incrementally. +// This can scan the whole table if needed (e.g. leaderboard-style queries). +spacetimedb.anonymousView( + { name: 'top_players', public: true }, + t.array(Player.rowType), + (ctx) => + ctx.from.player + .where(p => p.score.gt(1000)) +); +``` + +### ViewContext vs AnonymousViewContext +```typescript +// ViewContext — has ctx.sender, result varies per user (computed per-subscriber) +spacetimedb.view({ name: 'my_items', public: true }, t.array(Item.rowType), (ctx) => { + return [...ctx.db.item.by_owner.filter(ctx.sender)]; +}); + +// AnonymousViewContext — no ctx.sender, same result for everyone (shared, better perf) +spacetimedb.anonymousView({ name: 'leaderboard', public: true }, t.array(LeaderboardRow), (ctx) => { + return [...ctx.db.player.by_score.filter(/* top scores */)]; +}); +``` + +**Views require explicit subscription:** +```typescript +conn.subscriptionBuilder().subscribe([ + 'SELECT * FROM public_table', + 'SELECT * FROM my_data', // Views need explicit SQL! +]); +``` + +--- + +## 8) React Integration + +### Key patterns +```typescript +// Memoize connectionBuilder to prevent reconnects on re-render +const builder = useMemo(() => + DbConnection.builder() + .withUri(SPACETIMEDB_URI) + .withDatabaseName(MODULE_NAME) + .withToken(localStorage.getItem('auth_token') || undefined) + .onConnect(onConnect) + .onConnectError(onConnectError), + [] // Empty deps - only create once +); + +// useTable returns tuple [rows, isLoading] +const [rows, isLoading] = useTable(tables.myTable); + +// Compare identities using toHexString() +const isOwner = row.ownerId.toHexString() === myIdentity.toHexString(); +``` + +--- + +## 9) Procedures (Beta) + +**Procedures are for side effects (HTTP requests, etc.) that reducers can't do.** + +⚠️ Procedures are currently in beta. API may change. + +### Defining a procedure +**Procedure name comes from the export — NOT from a string argument.** Use `procedure(params, ret, fn)` or `procedure(ret, fn)`. + +```typescript +// ✅ CORRECT — export const name = spacetimedb.procedure(params, ret, fn) +export const fetch_external_data = spacetimedb.procedure( + { url: t.string() }, + t.string(), // return type + (ctx, { url }) => { + const response = ctx.http.fetch(url); + return response.text(); + } +); +``` + +### Database access in procedures + +⚠️ **CRITICAL: Procedures don't have `ctx.db`. Use `ctx.withTx()` for database access.** + +```typescript +spacetimedb.procedure({ url: t.string() }, t.unit(), (ctx, { url }) => { + // Fetch external data (outside transaction) + const response = ctx.http.fetch(url); + const data = response.text(); + + // ❌ WRONG — ctx.db doesn't exist in procedures + ctx.db.myTable.insert({ ... }); + + // ✅ RIGHT — use ctx.withTx() for database access + ctx.withTx(tx => { + tx.db.myTable.insert({ + id: 0n, + content: data, + fetchedAt: tx.timestamp, + fetchedBy: tx.sender, + }); + }); + + return {}; +}); +``` + +### Key differences from reducers +| Reducers | Procedures | +|----------|------------| +| `ctx.db` available directly | Must use `ctx.withTx(tx => tx.db...)` | +| Automatic transaction | Manual transaction management | +| No HTTP/network | `ctx.http.fetch()` available | +| No return values to caller | Can return data to caller | + +--- + +## 10) Project Structure + +### Server (`backend/spacetimedb/`) +``` +src/schema.ts → Tables, export spacetimedb +src/index.ts → Reducers, lifecycle, import schema +package.json → { "type": "module", "dependencies": { "spacetimedb": "^1.11.0" } } +tsconfig.json → Standard config +``` + +### Avoiding circular imports +``` +schema.ts → defines tables AND exports spacetimedb +index.ts → imports spacetimedb from ./schema, defines reducers +``` + +### Client (`client/`) +``` +src/module_bindings/ → Generated (spacetime generate) +src/main.tsx → Provider, connection setup +src/App.tsx → UI components +src/config.ts → MODULE_NAME, SPACETIMEDB_URI +``` + +--- + +## 11) Commands + +```bash +# Start local server +spacetime start + +# Publish module +spacetime publish --module-path + +# Clear database and republish +spacetime publish --clear-database -y --module-path + +# Generate bindings +spacetime generate --lang typescript --out-dir /src/module_bindings --module-path + +# View logs +spacetime logs +``` + +--- + +## 12) Hard Requirements + +**TypeScript-specific:** + +1. **`schema({ table })`** — takes exactly one object; never `schema(table)` or `schema(t1, t2, t3)` +2. **Reducer/procedure names from exports** — `export const name = spacetimedb.reducer(params, fn)`; never `reducer('name', ...)` +3. **Reducer calls use object syntax** — `{ param: 'value' }` not positional args +4. **Import `DbConnection` from `./module_bindings`** — not from `spacetimedb` +5. **DO NOT edit generated bindings** — regenerate with `spacetime generate` +6. **Indexes go in OPTIONS (1st arg)** — not in COLUMNS (2nd arg) of `table()` +7. **Use BigInt for u64/i64 fields** — `0n`, `1n`, not `0`, `1` +8. **Reducers are transactional** — they do not return data +9. **Reducers must be deterministic** — no filesystem, network, timers, random +10. **Views should use index lookups** — `.iter()` causes severe performance issues +11. **Procedures need `ctx.withTx()`** — `ctx.db` doesn't exist in procedures +12. **Sum type values** — use `{ tag: 'variant', value: payload }` not `{ variant: payload }` diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..982d9c5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2025 Clockwork Labs, Inc + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..92a1c58 --- /dev/null +++ b/README.md @@ -0,0 +1,67 @@ +# SpacetimeDB TypeScript Quickstart Chat + +This is a simple chat application that demonstrates how to use SpacetimeDB with TypeScript and React. The chat application is a simple chat room where users can send messages to each other. The chat application uses SpacetimeDB to store the chat messages. + +It is based directly on the plain React + TypeScript + Vite template. You can follow the quickstart guide for how creating this project from scratch at [SpacetimeDB TypeScript Quickstart](https://spacetimedb.com/docs/sdks/typescript/quickstart). + +You can follow the instructions for creating your own SpacetimeDB module here: [SpacetimeDB Rust Module Quickstart](https://spacetimedb.com/docs/modules/rust/quickstart). Place the module in the `quickstart-chat/server` directory for compability with this project. + +In order to run this example, you need to: + +- `pnpm build` in the root directory (`spacetimedb-typescriptsdk`) +- `pnpm install` in this directory +- `pnpm build` in this directory +- `pnpm dev` in this directory to run the example + +Below is copied from the original template README: + +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: + +- Configure the top-level `parserOptions` property like this: + +```js +export default tseslint.config({ + languageOptions: { + // other options... + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + }, +}); +``` + +- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked` +- Optionally add `...tseslint.configs.stylisticTypeChecked` +- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config: + +```js +// eslint.config.js +import react from 'eslint-plugin-react'; + +export default tseslint.config({ + // Set the react version + settings: { react: { version: '18.3' } }, + plugins: { + // Add the react plugin + react, + }, + rules: { + // other rules... + // Enable its recommended rules + ...react.configs.recommended.rules, + ...react.configs['jsx-runtime'].rules, + }, +}); +``` diff --git a/dist/assets/index-DnMf931V.js b/dist/assets/index-DnMf931V.js new file mode 100644 index 0000000..5ea303c --- /dev/null +++ b/dist/assets/index-DnMf931V.js @@ -0,0 +1,86 @@ +(function(){const n=document.createElement("link").relList;if(n&&n.supports&&n.supports("modulepreload"))return;for(const c of document.querySelectorAll('link[rel="modulepreload"]'))a(c);new MutationObserver(c=>{for(const f of c)if(f.type==="childList")for(const p of f.addedNodes)p.tagName==="LINK"&&p.rel==="modulepreload"&&a(p)}).observe(document,{childList:!0,subtree:!0});function s(c){const f={};return c.integrity&&(f.integrity=c.integrity),c.referrerPolicy&&(f.referrerPolicy=c.referrerPolicy),c.crossOrigin==="use-credentials"?f.credentials="include":c.crossOrigin==="anonymous"?f.credentials="omit":f.credentials="same-origin",f}function a(c){if(c.ep)return;c.ep=!0;const f=s(c);fetch(c.href,f)}})();function yh(r){return r&&r.__esModule&&Object.prototype.hasOwnProperty.call(r,"default")?r.default:r}var ru={exports:{}},ws={},nu={exports:{}},ve={};var Nf;function xm(){if(Nf)return ve;Nf=1;var r=Symbol.for("react.element"),n=Symbol.for("react.portal"),s=Symbol.for("react.fragment"),a=Symbol.for("react.strict_mode"),c=Symbol.for("react.profiler"),f=Symbol.for("react.provider"),p=Symbol.for("react.context"),v=Symbol.for("react.forward_ref"),y=Symbol.for("react.suspense"),x=Symbol.for("react.memo"),R=Symbol.for("react.lazy"),N=Symbol.iterator;function j(w){return w===null||typeof w!="object"?null:(w=N&&w[N]||w["@@iterator"],typeof w=="function"?w:null)}var O={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},q=Object.assign,Q={};function $(w,E,ee){this.props=w,this.context=E,this.refs=Q,this.updater=ee||O}$.prototype.isReactComponent={},$.prototype.setState=function(w,E){if(typeof w!="object"&&typeof w!="function"&&w!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,w,E,"setState")},$.prototype.forceUpdate=function(w){this.updater.enqueueForceUpdate(this,w,"forceUpdate")};function fe(){}fe.prototype=$.prototype;function T(w,E,ee){this.props=w,this.context=E,this.refs=Q,this.updater=ee||O}var A=T.prototype=new fe;A.constructor=T,q(A,$.prototype),A.isPureReactComponent=!0;var L=Array.isArray,J=Object.prototype.hasOwnProperty,Y={current:null},ge={key:!0,ref:!0,__self:!0,__source:!0};function me(w,E,ee){var ne,te={},le=null,ie=null;if(E!=null)for(ne in E.ref!==void 0&&(ie=E.ref),E.key!==void 0&&(le=""+E.key),E)J.call(E,ne)&&!ge.hasOwnProperty(ne)&&(te[ne]=E[ne]);var he=arguments.length-2;if(he===1)te.children=ee;else if(1>>1,E=M[w];if(0>>1;wc(te,z))lec(ie,te)?(M[w]=ie,M[le]=z,w=le):(M[w]=te,M[ne]=z,w=ne);else if(lec(ie,z))M[w]=ie,M[le]=z,w=le;else break e}}return H}function c(M,H){var z=M.sortIndex-H.sortIndex;return z!==0?z:M.id-H.id}if(typeof performance=="object"&&typeof performance.now=="function"){var f=performance;r.unstable_now=function(){return f.now()}}else{var p=Date,v=p.now();r.unstable_now=function(){return p.now()-v}}var y=[],x=[],R=1,N=null,j=3,O=!1,q=!1,Q=!1,$=typeof setTimeout=="function"?setTimeout:null,fe=typeof clearTimeout=="function"?clearTimeout:null,T=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function A(M){for(var H=s(x);H!==null;){if(H.callback===null)a(x);else if(H.startTime<=M)a(x),H.sortIndex=H.expirationTime,n(y,H);else break;H=s(x)}}function L(M){if(Q=!1,A(M),!q)if(s(y)!==null)q=!0,P(J);else{var H=s(x);H!==null&&W(L,H.startTime-M)}}function J(M,H){q=!1,Q&&(Q=!1,fe(me),me=-1),O=!0;var z=j;try{for(A(H),N=s(y);N!==null&&(!(N.expirationTime>H)||M&&!We());){var w=N.callback;if(typeof w=="function"){N.callback=null,j=N.priorityLevel;var E=w(N.expirationTime<=H);H=r.unstable_now(),typeof E=="function"?N.callback=E:N===s(y)&&a(y),A(H)}else a(y);N=s(y)}if(N!==null)var ee=!0;else{var ne=s(x);ne!==null&&W(L,ne.startTime-H),ee=!1}return ee}finally{N=null,j=z,O=!1}}var Y=!1,ge=null,me=-1,ue=5,Re=-1;function We(){return!(r.unstable_now()-ReM||125w?(M.sortIndex=z,n(x,M),s(y)===null&&M===s(x)&&(Q?(fe(me),me=-1):Q=!0,W(L,z-w))):(M.sortIndex=E,n(y,M),q||O||(q=!0,P(J))),M},r.unstable_shouldYield=We,r.unstable_wrapCallback=function(M){var H=j;return function(){var z=j;j=H;try{return M.apply(this,arguments)}finally{j=z}}}})(ou)),ou}var jf;function Cm(){return jf||(jf=1,su.exports=bm()),su.exports}var Of;function Tm(){if(Of)return wt;Of=1;var r=Au(),n=Cm();function s(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,i=1;i"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),y=Object.prototype.hasOwnProperty,x=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,R={},N={};function j(e){return y.call(N,e)?!0:y.call(R,e)?!1:x.test(e)?N[e]=!0:(R[e]=!0,!1)}function O(e,t,i,o){if(i!==null&&i.type===0)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return o?!1:i!==null?!i.acceptsBooleans:(e=e.toLowerCase().slice(0,5),e!=="data-"&&e!=="aria-");default:return!1}}function q(e,t,i,o){if(t===null||typeof t>"u"||O(e,t,i,o))return!0;if(o)return!1;if(i!==null)switch(i.type){case 3:return!t;case 4:return t===!1;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}function Q(e,t,i,o,l,u,h){this.acceptsBooleans=t===2||t===3||t===4,this.attributeName=o,this.attributeNamespace=l,this.mustUseProperty=i,this.propertyName=e,this.type=t,this.sanitizeURL=u,this.removeEmptyString=h}var $={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(e){$[e]=new Q(e,0,!1,e,null,!1,!1)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0];$[t]=new Q(t,1,!1,e[1],null,!1,!1)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){$[e]=new Q(e,2,!1,e.toLowerCase(),null,!1,!1)}),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(e){$[e]=new Q(e,2,!1,e,null,!1,!1)}),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(e){$[e]=new Q(e,3,!1,e.toLowerCase(),null,!1,!1)}),["checked","multiple","muted","selected"].forEach(function(e){$[e]=new Q(e,3,!0,e,null,!1,!1)}),["capture","download"].forEach(function(e){$[e]=new Q(e,4,!1,e,null,!1,!1)}),["cols","rows","size","span"].forEach(function(e){$[e]=new Q(e,6,!1,e,null,!1,!1)}),["rowSpan","start"].forEach(function(e){$[e]=new Q(e,5,!1,e.toLowerCase(),null,!1,!1)});var fe=/[\-:]([a-z])/g;function T(e){return e[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(e){var t=e.replace(fe,T);$[t]=new Q(t,1,!1,e,null,!1,!1)}),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(e){var t=e.replace(fe,T);$[t]=new Q(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)}),["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(fe,T);$[t]=new Q(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)}),["tabIndex","crossOrigin"].forEach(function(e){$[e]=new Q(e,1,!1,e.toLowerCase(),null,!1,!1)}),$.xlinkHref=new Q("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach(function(e){$[e]=new Q(e,1,!1,e.toLowerCase(),null,!0,!0)});function A(e,t,i,o){var l=$.hasOwnProperty(t)?$[t]:null;(l!==null?l.type!==0:o||!(2m||l[h]!==u[m]){var _=` +`+l[h].replace(" at new "," at ");return e.displayName&&_.includes("")&&(_=_.replace("",e.displayName)),_}while(1<=h&&0<=m);break}}}finally{ee=!1,Error.prepareStackTrace=i}return(e=e?e.displayName||e.name:"")?E(e):""}function te(e){switch(e.tag){case 5:return E(e.type);case 16:return E("Lazy");case 13:return E("Suspense");case 19:return E("SuspenseList");case 0:case 2:case 15:return e=ne(e.type,!1),e;case 11:return e=ne(e.type.render,!1),e;case 1:return e=ne(e.type,!0),e;default:return""}}function le(e){if(e==null)return null;if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case ge:return"Fragment";case Y:return"Portal";case ue:return"Profiler";case me:return"StrictMode";case Me:return"Suspense";case it:return"SuspenseList"}if(typeof e=="object")switch(e.$$typeof){case We:return(e.displayName||"Context")+".Consumer";case Re:return(e._context.displayName||"Context")+".Provider";case Le:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case ke:return t=e.displayName||null,t!==null?t:le(e.type)||"Memo";case P:t=e._payload,e=e._init;try{return le(e(t))}catch{}}return null}function ie(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=t.render,e=e.displayName||e.name||"",t.displayName||(e!==""?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return le(t);case 8:return t===me?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t}return null}function he(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":return e;case"object":return e;default:return""}}function we(e){var t=e.type;return(e=e.nodeName)&&e.toLowerCase()==="input"&&(t==="checkbox"||t==="radio")}function _e(e){var t=we(e)?"checked":"value",i=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),o=""+e[t];if(!e.hasOwnProperty(t)&&typeof i<"u"&&typeof i.get=="function"&&typeof i.set=="function"){var l=i.get,u=i.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return l.call(this)},set:function(h){o=""+h,u.call(this,h)}}),Object.defineProperty(e,t,{enumerable:i.enumerable}),{getValue:function(){return o},setValue:function(h){o=""+h},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}function Ne(e){e._valueTracker||(e._valueTracker=_e(e))}function Ge(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var i=t.getValue(),o="";return e&&(o=we(e)?e.checked?"true":"false":e.value),e=o,e!==i?(t.setValue(e),!0):!1}function Dt(e){if(e=e||(typeof document<"u"?document:void 0),typeof e>"u")return null;try{return e.activeElement||e.body}catch{return e.body}}function mr(e,t){var i=t.checked;return z({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:i??e._wrapperState.initialChecked})}function Dr(e,t){var i=t.defaultValue==null?"":t.defaultValue,o=t.checked!=null?t.checked:t.defaultChecked;i=he(t.value!=null?t.value:i),e._wrapperState={initialChecked:o,initialValue:i,controlled:t.type==="checkbox"||t.type==="radio"?t.checked!=null:t.value!=null}}function Sn(e,t){t=t.checked,t!=null&&A(e,"checked",t,!1)}function zr(e,t){Sn(e,t);var i=he(t.value),o=t.type;if(i!=null)o==="number"?(i===0&&e.value===""||e.value!=i)&&(e.value=""+i):e.value!==""+i&&(e.value=""+i);else if(o==="submit"||o==="reset"){e.removeAttribute("value");return}t.hasOwnProperty("value")?Ri(e,t.type,i):t.hasOwnProperty("defaultValue")&&Ri(e,t.type,he(t.defaultValue)),t.checked==null&&t.defaultChecked!=null&&(e.defaultChecked=!!t.defaultChecked)}function Ui(e,t,i){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var o=t.type;if(!(o!=="submit"&&o!=="reset"||t.value!==void 0&&t.value!==null))return;t=""+e._wrapperState.initialValue,i||t===e.value||(e.value=t),e.defaultValue=t}i=e.name,i!==""&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,i!==""&&(e.name=i)}function Ri(e,t,i){(t!=="number"||Dt(e.ownerDocument)!==e)&&(i==null?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+i&&(e.defaultValue=""+i))}var Fr=Array.isArray;function yr(e,t,i,o){if(e=e.options,t){t={};for(var l=0;l"+t.valueOf().toString()+"",t=xt.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}});function $r(e,t){if(t){var i=e.firstChild;if(i&&i===e.lastChild&&i.nodeType===3){i.nodeValue=t;return}}e.textContent=t}var Lr={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},ya=["Webkit","ms","Moz","O"];Object.keys(Lr).forEach(function(e){ya.forEach(function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),Lr[t]=Lr[e]})});function Os(e,t,i){return t==null||typeof t=="boolean"||t===""?"":i||typeof t!="number"||t===0||Lr.hasOwnProperty(e)&&Lr[e]?(""+t).trim():t+"px"}function Ds(e,t){e=e.style;for(var i in t)if(t.hasOwnProperty(i)){var o=i.indexOf("--")===0,l=Os(i,t[i],o);i==="float"&&(i="cssFloat"),o?e.setProperty(i,l):e[i]=l}}var wa=z({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function Bi(e,t){if(t){if(wa[e]&&(t.children!=null||t.dangerouslySetInnerHTML!=null))throw Error(s(137,e));if(t.dangerouslySetInnerHTML!=null){if(t.children!=null)throw Error(s(60));if(typeof t.dangerouslySetInnerHTML!="object"||!("__html"in t.dangerouslySetInnerHTML))throw Error(s(61))}if(t.style!=null&&typeof t.style!="object")throw Error(s(62))}}function Ai(e,t){if(e.indexOf("-")===-1)return typeof t.is=="string";switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var zs=null;function Et(e){return e=e.target||e.srcElement||window,e.correspondingUseElement&&(e=e.correspondingUseElement),e.nodeType===3?e.parentNode:e}var Mi=null,B=null,ye=null;function bn(e){if(e=ns(e)){if(typeof Mi!="function")throw Error(s(280));var t=e.stateNode;t&&(t=lo(t),Mi(e.stateNode,e.type,t))}}function Qu(e){B?ye?ye.push(e):ye=[e]:B=e}function Ju(){if(B){var e=B,t=ye;if(ye=B=null,bn(e),t)for(e=0;e>>=0,e===0?32:31-(Dp(e)/zp|0)|0}var qs=64,Hs=4194304;function zi(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return e&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return e&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function Ks(e,t){var i=e.pendingLanes;if(i===0)return 0;var o=0,l=e.suspendedLanes,u=e.pingedLanes,h=i&268435455;if(h!==0){var m=h&~l;m!==0?o=zi(m):(u&=h,u!==0&&(o=zi(u)))}else h=i&~l,h!==0?o=zi(h):u!==0&&(o=zi(u));if(o===0)return 0;if(t!==0&&t!==o&&(t&l)===0&&(l=o&-o,u=t&-t,l>=u||l===16&&(u&4194240)!==0))return t;if((o&4)!==0&&(o|=i&16),t=e.entangledLanes,t!==0)for(e=e.entanglements,t&=o;0i;i++)t.push(e);return t}function Fi(e,t,i){e.pendingLanes|=t,t!==536870912&&(e.suspendedLanes=0,e.pingedLanes=0),e=e.eventTimes,t=31-zt(t),e[t]=i}function Vp(e,t){var i=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var o=e.eventTimes;for(e=e.expirationTimes;0=Qi),Ic=" ",kc=!1;function bc(e,t){switch(e){case"keyup":return yg.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Cc(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var En=!1;function vg(e,t){switch(e){case"compositionend":return Cc(t);case"keypress":return t.which!==32?null:(kc=!0,Ic);case"textInput":return e=t.data,e===Ic&&kc?null:e;default:return null}}function _g(e,t){if(En)return e==="compositionend"||!ja&&bc(e,t)?(e=yc(),Xs=Ra=xr=null,En=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:i,offset:t-e};e=o}e:{for(;i;){if(i.nextSibling){i=i.nextSibling;break e}i=i.parentNode}i=void 0}i=Bc(i)}}function Mc(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?Mc(e,t.parentNode):"contains"in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function jc(){for(var e=window,t=Dt();t instanceof e.HTMLIFrameElement;){try{var i=typeof t.contentWindow.location.href=="string"}catch{i=!1}if(i)e=t.contentWindow;else break;t=Dt(e.document)}return t}function za(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||t==="textarea"||e.contentEditable==="true")}function Ug(e){var t=jc(),i=e.focusedElem,o=e.selectionRange;if(t!==i&&i&&i.ownerDocument&&Mc(i.ownerDocument.documentElement,i)){if(o!==null&&za(i)){if(t=o.start,e=o.end,e===void 0&&(e=t),"selectionStart"in i)i.selectionStart=t,i.selectionEnd=Math.min(e,i.value.length);else if(e=(t=i.ownerDocument||document)&&t.defaultView||window,e.getSelection){e=e.getSelection();var l=i.textContent.length,u=Math.min(o.start,l);o=o.end===void 0?u:Math.min(o.end,l),!e.extend&&u>o&&(l=o,o=u,u=l),l=Ac(i,u);var h=Ac(i,o);l&&h&&(e.rangeCount!==1||e.anchorNode!==l.node||e.anchorOffset!==l.offset||e.focusNode!==h.node||e.focusOffset!==h.offset)&&(t=t.createRange(),t.setStart(l.node,l.offset),e.removeAllRanges(),u>o?(e.addRange(t),e.extend(h.node,h.offset)):(t.setEnd(h.node,h.offset),e.addRange(t)))}}for(t=[],e=i;e=e.parentNode;)e.nodeType===1&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for(typeof i.focus=="function"&&i.focus(),i=0;i=document.documentMode,Un=null,Fa=null,Yi=null,$a=!1;function Oc(e,t,i){var o=i.window===i?i.document:i.nodeType===9?i:i.ownerDocument;$a||Un==null||Un!==Dt(o)||(o=Un,"selectionStart"in o&&za(o)?o={start:o.selectionStart,end:o.selectionEnd}:(o=(o.ownerDocument&&o.ownerDocument.defaultView||window).getSelection(),o={anchorNode:o.anchorNode,anchorOffset:o.anchorOffset,focusNode:o.focusNode,focusOffset:o.focusOffset}),Yi&&Xi(Yi,o)||(Yi=o,o=so(Fa,"onSelect"),0An||(e.current=Za[An],Za[An]=null,An--)}function Ae(e,t){An++,Za[An]=e.current,e.current=t}var Cr={},at=br(Cr),ht=br(!1),Hr=Cr;function Mn(e,t){var i=e.type.contextTypes;if(!i)return Cr;var o=e.stateNode;if(o&&o.__reactInternalMemoizedUnmaskedChildContext===t)return o.__reactInternalMemoizedMaskedChildContext;var l={},u;for(u in i)l[u]=t[u];return o&&(e=e.stateNode,e.__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=l),l}function pt(e){return e=e.childContextTypes,e!=null}function uo(){Oe(ht),Oe(at)}function Yc(e,t,i){if(at.current!==Cr)throw Error(s(168));Ae(at,t),Ae(ht,i)}function Zc(e,t,i){var o=e.stateNode;if(t=t.childContextTypes,typeof o.getChildContext!="function")return i;o=o.getChildContext();for(var l in o)if(!(l in t))throw Error(s(108,ie(e)||"Unknown",l));return z({},i,o)}function co(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Cr,Hr=at.current,Ae(at,e),Ae(ht,ht.current),!0}function ed(e,t,i){var o=e.stateNode;if(!o)throw Error(s(169));i?(e=Zc(e,t,Hr),o.__reactInternalMemoizedMergedChildContext=e,Oe(ht),Oe(at),Ae(at,e)):Oe(ht),Ae(ht,i)}var ir=null,fo=!1,el=!1;function td(e){ir===null?ir=[e]:ir.push(e)}function $g(e){fo=!0,td(e)}function Tr(){if(!el&&ir!==null){el=!0;var e=0,t=Ue;try{var i=ir;for(Ue=1;e>=h,l-=h,sr=1<<32-zt(t)+l|i<pe?(nt=de,de=null):nt=de.sibling;var Ce=D(I,de,k[pe],K);if(Ce===null){de===null&&(de=nt);break}e&&de&&Ce.alternate===null&&t(I,de),S=u(Ce,S,pe),ce===null?se=Ce:ce.sibling=Ce,ce=Ce,de=nt}if(pe===k.length)return i(I,de),De&&Wr(I,pe),se;if(de===null){for(;pepe?(nt=de,de=null):nt=de.sibling;var jr=D(I,de,Ce.value,K);if(jr===null){de===null&&(de=nt);break}e&&de&&jr.alternate===null&&t(I,de),S=u(jr,S,pe),ce===null?se=jr:ce.sibling=jr,ce=jr,de=nt}if(Ce.done)return i(I,de),De&&Wr(I,pe),se;if(de===null){for(;!Ce.done;pe++,Ce=k.next())Ce=V(I,Ce.value,K),Ce!==null&&(S=u(Ce,S,pe),ce===null?se=Ce:ce.sibling=Ce,ce=Ce);return De&&Wr(I,pe),se}for(de=o(I,de);!Ce.done;pe++,Ce=k.next())Ce=G(de,I,pe,Ce.value,K),Ce!==null&&(e&&Ce.alternate!==null&&de.delete(Ce.key===null?pe:Ce.key),S=u(Ce,S,pe),ce===null?se=Ce:ce.sibling=Ce,ce=Ce);return e&&de.forEach(function(Sm){return t(I,Sm)}),De&&Wr(I,pe),se}function He(I,S,k,K){if(typeof k=="object"&&k!==null&&k.type===ge&&k.key===null&&(k=k.props.children),typeof k=="object"&&k!==null){switch(k.$$typeof){case J:e:{for(var se=k.key,ce=S;ce!==null;){if(ce.key===se){if(se=k.type,se===ge){if(ce.tag===7){i(I,ce.sibling),S=l(ce,k.props.children),S.return=I,I=S;break e}}else if(ce.elementType===se||typeof se=="object"&&se!==null&&se.$$typeof===P&&ad(se)===ce.type){i(I,ce.sibling),S=l(ce,k.props),S.ref=is(I,ce,k),S.return=I,I=S;break e}i(I,ce);break}else t(I,ce);ce=ce.sibling}k.type===ge?(S=tn(k.props.children,I.mode,K,k.key),S.return=I,I=S):(K=Fo(k.type,k.key,k.props,null,I.mode,K),K.ref=is(I,S,k),K.return=I,I=K)}return h(I);case Y:e:{for(ce=k.key;S!==null;){if(S.key===ce)if(S.tag===4&&S.stateNode.containerInfo===k.containerInfo&&S.stateNode.implementation===k.implementation){i(I,S.sibling),S=l(S,k.children||[]),S.return=I,I=S;break e}else{i(I,S);break}else t(I,S);S=S.sibling}S=Xl(k,I.mode,K),S.return=I,I=S}return h(I);case P:return ce=k._init,He(I,S,ce(k._payload),K)}if(Fr(k))return Z(I,S,k,K);if(H(k))return re(I,S,k,K);mo(I,k)}return typeof k=="string"&&k!==""||typeof k=="number"?(k=""+k,S!==null&&S.tag===6?(i(I,S.sibling),S=l(S,k),S.return=I,I=S):(i(I,S),S=Gl(k,I.mode,K),S.return=I,I=S),h(I)):i(I,S)}return He}var zn=ld(!0),ud=ld(!1),yo=br(null),wo=null,Fn=null,ol=null;function al(){ol=Fn=wo=null}function ll(e){var t=yo.current;Oe(yo),e._currentValue=t}function ul(e,t,i){for(;e!==null;){var o=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,o!==null&&(o.childLanes|=t)):o!==null&&(o.childLanes&t)!==t&&(o.childLanes|=t),e===i)break;e=e.return}}function $n(e,t){wo=e,ol=Fn=null,e=e.dependencies,e!==null&&e.firstContext!==null&&((e.lanes&t)!==0&&(gt=!0),e.firstContext=null)}function Nt(e){var t=e._currentValue;if(ol!==e)if(e={context:e,memoizedValue:t,next:null},Fn===null){if(wo===null)throw Error(s(308));Fn=e,wo.dependencies={lanes:0,firstContext:e}}else Fn=Fn.next=e;return t}var Qr=null;function cl(e){Qr===null?Qr=[e]:Qr.push(e)}function cd(e,t,i,o){var l=t.interleaved;return l===null?(i.next=i,cl(t)):(i.next=l.next,l.next=i),t.interleaved=i,ar(e,o)}function ar(e,t){e.lanes|=t;var i=e.alternate;for(i!==null&&(i.lanes|=t),i=e,e=e.return;e!==null;)e.childLanes|=t,i=e.alternate,i!==null&&(i.childLanes|=t),i=e,e=e.return;return i.tag===3?i.stateNode:null}var Er=!1;function dl(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function dd(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function lr(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function Ur(e,t,i){var o=e.updateQueue;if(o===null)return null;if(o=o.shared,(be&2)!==0){var l=o.pending;return l===null?t.next=t:(t.next=l.next,l.next=t),o.pending=t,ar(e,i)}return l=o.interleaved,l===null?(t.next=t,cl(o)):(t.next=l.next,l.next=t),o.interleaved=t,ar(e,i)}function vo(e,t,i){if(t=t.updateQueue,t!==null&&(t=t.shared,(i&4194240)!==0)){var o=t.lanes;o&=e.pendingLanes,i|=o,t.lanes=i,ba(e,i)}}function fd(e,t){var i=e.updateQueue,o=e.alternate;if(o!==null&&(o=o.updateQueue,i===o)){var l=null,u=null;if(i=i.firstBaseUpdate,i!==null){do{var h={eventTime:i.eventTime,lane:i.lane,tag:i.tag,payload:i.payload,callback:i.callback,next:null};u===null?l=u=h:u=u.next=h,i=i.next}while(i!==null);u===null?l=u=t:u=u.next=t}else l=u=t;i={baseState:o.baseState,firstBaseUpdate:l,lastBaseUpdate:u,shared:o.shared,effects:o.effects},e.updateQueue=i;return}e=i.lastBaseUpdate,e===null?i.firstBaseUpdate=t:e.next=t,i.lastBaseUpdate=t}function _o(e,t,i,o){var l=e.updateQueue;Er=!1;var u=l.firstBaseUpdate,h=l.lastBaseUpdate,m=l.shared.pending;if(m!==null){l.shared.pending=null;var _=m,C=_.next;_.next=null,h===null?u=C:h.next=C,h=_;var F=e.alternate;F!==null&&(F=F.updateQueue,m=F.lastBaseUpdate,m!==h&&(m===null?F.firstBaseUpdate=C:m.next=C,F.lastBaseUpdate=_))}if(u!==null){var V=l.baseState;h=0,F=C=_=null,m=u;do{var D=m.lane,G=m.eventTime;if((o&D)===D){F!==null&&(F=F.next={eventTime:G,lane:0,tag:m.tag,payload:m.payload,callback:m.callback,next:null});e:{var Z=e,re=m;switch(D=t,G=i,re.tag){case 1:if(Z=re.payload,typeof Z=="function"){V=Z.call(G,V,D);break e}V=Z;break e;case 3:Z.flags=Z.flags&-65537|128;case 0:if(Z=re.payload,D=typeof Z=="function"?Z.call(G,V,D):Z,D==null)break e;V=z({},V,D);break e;case 2:Er=!0}}m.callback!==null&&m.lane!==0&&(e.flags|=64,D=l.effects,D===null?l.effects=[m]:D.push(m))}else G={eventTime:G,lane:D,tag:m.tag,payload:m.payload,callback:m.callback,next:null},F===null?(C=F=G,_=V):F=F.next=G,h|=D;if(m=m.next,m===null){if(m=l.shared.pending,m===null)break;D=m,m=D.next,D.next=null,l.lastBaseUpdate=D,l.shared.pending=null}}while(!0);if(F===null&&(_=V),l.baseState=_,l.firstBaseUpdate=C,l.lastBaseUpdate=F,t=l.shared.interleaved,t!==null){l=t;do h|=l.lane,l=l.next;while(l!==t)}else u===null&&(l.shared.lanes=0);Xr|=h,e.lanes=h,e.memoizedState=V}}function hd(e,t,i){if(e=t.effects,t.effects=null,e!==null)for(t=0;ti?i:4,e(!0);var o=ml.transition;ml.transition={};try{e(!1),t()}finally{Ue=i,ml.transition=o}}function Pd(){return Pt().memoizedState}function Hg(e,t,i){var o=Br(e);if(i={lane:o,action:i,hasEagerState:!1,eagerState:null,next:null},Bd(e))Ad(t,i);else if(i=cd(e,t,i,o),i!==null){var l=ft();Ht(i,e,o,l),Md(i,t,o)}}function Kg(e,t,i){var o=Br(e),l={lane:o,action:i,hasEagerState:!1,eagerState:null,next:null};if(Bd(e))Ad(t,l);else{var u=e.alternate;if(e.lanes===0&&(u===null||u.lanes===0)&&(u=t.lastRenderedReducer,u!==null))try{var h=t.lastRenderedState,m=u(h,i);if(l.hasEagerState=!0,l.eagerState=m,Ft(m,h)){var _=t.interleaved;_===null?(l.next=l,cl(t)):(l.next=_.next,_.next=l),t.interleaved=l;return}}catch{}i=cd(e,t,l,o),i!==null&&(l=ft(),Ht(i,e,o,l),Md(i,t,o))}}function Bd(e){var t=e.alternate;return e===$e||t!==null&&t===$e}function Ad(e,t){ls=Io=!0;var i=e.pending;i===null?t.next=t:(t.next=i.next,i.next=t),e.pending=t}function Md(e,t,i){if((i&4194240)!==0){var o=t.lanes;o&=e.pendingLanes,i|=o,t.lanes=i,ba(e,i)}}var Co={readContext:Nt,useCallback:lt,useContext:lt,useEffect:lt,useImperativeHandle:lt,useInsertionEffect:lt,useLayoutEffect:lt,useMemo:lt,useReducer:lt,useRef:lt,useState:lt,useDebugValue:lt,useDeferredValue:lt,useTransition:lt,useMutableSource:lt,useSyncExternalStore:lt,useId:lt,unstable_isNewReconciler:!1},Wg={readContext:Nt,useCallback:function(e,t){return Xt().memoizedState=[e,t===void 0?null:t],e},useContext:Nt,useEffect:kd,useImperativeHandle:function(e,t,i){return i=i!=null?i.concat([e]):null,ko(4194308,4,Td.bind(null,t,e),i)},useLayoutEffect:function(e,t){return ko(4194308,4,e,t)},useInsertionEffect:function(e,t){return ko(4,2,e,t)},useMemo:function(e,t){var i=Xt();return t=t===void 0?null:t,e=e(),i.memoizedState=[e,t],e},useReducer:function(e,t,i){var o=Xt();return t=i!==void 0?i(t):t,o.memoizedState=o.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},o.queue=e,e=e.dispatch=Hg.bind(null,$e,e),[o.memoizedState,e]},useRef:function(e){var t=Xt();return e={current:e},t.memoizedState=e},useState:xd,useDebugValue:Il,useDeferredValue:function(e){return Xt().memoizedState=e},useTransition:function(){var e=xd(!1),t=e[0];return e=qg.bind(null,e[1]),Xt().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,i){var o=$e,l=Xt();if(De){if(i===void 0)throw Error(s(407));i=i()}else{if(i=t(),rt===null)throw Error(s(349));(Gr&30)!==0||yd(o,t,i)}l.memoizedState=i;var u={value:i,getSnapshot:t};return l.queue=u,kd(vd.bind(null,o,u,e),[e]),o.flags|=2048,ds(9,wd.bind(null,o,u,i,t),void 0,null),i},useId:function(){var e=Xt(),t=rt.identifierPrefix;if(De){var i=or,o=sr;i=(o&~(1<<32-zt(o)-1)).toString(32)+i,t=":"+t+"R"+i,i=us++,0<\/script>",e=e.removeChild(e.firstChild)):typeof o.is=="string"?e=h.createElement(i,{is:o.is}):(e=h.createElement(i),i==="select"&&(h=e,o.multiple?h.multiple=!0:o.size&&(h.size=o.size))):e=h.createElementNS(e,i),e[Jt]=t,e[rs]=o,tf(e,t,!1,!1),t.stateNode=e;e:{switch(h=Ai(i,o),i){case"dialog":je("cancel",e),je("close",e),l=o;break;case"iframe":case"object":case"embed":je("load",e),l=o;break;case"video":case"audio":for(l=0;lKn&&(t.flags|=128,o=!0,fs(u,!1),t.lanes=4194304)}else{if(!o)if(e=So(h),e!==null){if(t.flags|=128,o=!0,i=e.updateQueue,i!==null&&(t.updateQueue=i,t.flags|=4),fs(u,!0),u.tail===null&&u.tailMode==="hidden"&&!h.alternate&&!De)return ut(t),null}else 2*qe()-u.renderingStartTime>Kn&&i!==1073741824&&(t.flags|=128,o=!0,fs(u,!1),t.lanes=4194304);u.isBackwards?(h.sibling=t.child,t.child=h):(i=u.last,i!==null?i.sibling=h:t.child=h,u.last=h)}return u.tail!==null?(t=u.tail,u.rendering=t,u.tail=t.sibling,u.renderingStartTime=qe(),t.sibling=null,i=Fe.current,Ae(Fe,o?i&1|2:i&1),t):(ut(t),null);case 22:case 23:return Wl(),o=t.memoizedState!==null,e!==null&&e.memoizedState!==null!==o&&(t.flags|=8192),o&&(t.mode&1)!==0?(Ct&1073741824)!==0&&(ut(t),t.subtreeFlags&6&&(t.flags|=8192)):ut(t),null;case 24:return null;case 25:return null}throw Error(s(156,t.tag))}function tm(e,t){switch(rl(t),t.tag){case 1:return pt(t.type)&&uo(),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Ln(),Oe(ht),Oe(at),gl(),e=t.flags,(e&65536)!==0&&(e&128)===0?(t.flags=e&-65537|128,t):null;case 5:return hl(t),null;case 13:if(Oe(Fe),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(s(340));Dn()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return Oe(Fe),null;case 4:return Ln(),null;case 10:return ll(t.type._context),null;case 22:case 23:return Wl(),null;case 24:return null;default:return null}}var Ro=!1,ct=!1,rm=typeof WeakSet=="function"?WeakSet:Set,X=null;function qn(e,t){var i=e.ref;if(i!==null)if(typeof i=="function")try{i(null)}catch(o){Ve(e,t,o)}else i.current=null}function Ml(e,t,i){try{i()}catch(o){Ve(e,t,o)}}var sf=!1;function nm(e,t){if(Wa=Js,e=jc(),za(e)){if("selectionStart"in e)var i={start:e.selectionStart,end:e.selectionEnd};else e:{i=(i=e.ownerDocument)&&i.defaultView||window;var o=i.getSelection&&i.getSelection();if(o&&o.rangeCount!==0){i=o.anchorNode;var l=o.anchorOffset,u=o.focusNode;o=o.focusOffset;try{i.nodeType,u.nodeType}catch{i=null;break e}var h=0,m=-1,_=-1,C=0,F=0,V=e,D=null;t:for(;;){for(var G;V!==i||l!==0&&V.nodeType!==3||(m=h+l),V!==u||o!==0&&V.nodeType!==3||(_=h+o),V.nodeType===3&&(h+=V.nodeValue.length),(G=V.firstChild)!==null;)D=V,V=G;for(;;){if(V===e)break t;if(D===i&&++C===l&&(m=h),D===u&&++F===o&&(_=h),(G=V.nextSibling)!==null)break;V=D,D=V.parentNode}V=G}i=m===-1||_===-1?null:{start:m,end:_}}else i=null}i=i||{start:0,end:0}}else i=null;for(Qa={focusedElem:e,selectionRange:i},Js=!1,X=t;X!==null;)if(t=X,e=t.child,(t.subtreeFlags&1028)!==0&&e!==null)e.return=t,X=e;else for(;X!==null;){t=X;try{var Z=t.alternate;if((t.flags&1024)!==0)switch(t.tag){case 0:case 11:case 15:break;case 1:if(Z!==null){var re=Z.memoizedProps,He=Z.memoizedState,I=t.stateNode,S=I.getSnapshotBeforeUpdate(t.elementType===t.type?re:Lt(t.type,re),He);I.__reactInternalSnapshotBeforeUpdate=S}break;case 3:var k=t.stateNode.containerInfo;k.nodeType===1?k.textContent="":k.nodeType===9&&k.documentElement&&k.removeChild(k.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(s(163))}}catch(K){Ve(t,t.return,K)}if(e=t.sibling,e!==null){e.return=t.return,X=e;break}X=t.return}return Z=sf,sf=!1,Z}function hs(e,t,i){var o=t.updateQueue;if(o=o!==null?o.lastEffect:null,o!==null){var l=o=o.next;do{if((l.tag&e)===e){var u=l.destroy;l.destroy=void 0,u!==void 0&&Ml(t,i,u)}l=l.next}while(l!==o)}}function No(e,t){if(t=t.updateQueue,t=t!==null?t.lastEffect:null,t!==null){var i=t=t.next;do{if((i.tag&e)===e){var o=i.create;i.destroy=o()}i=i.next}while(i!==t)}}function jl(e){var t=e.ref;if(t!==null){var i=e.stateNode;e.tag,e=i,typeof t=="function"?t(e):t.current=e}}function of(e){var t=e.alternate;t!==null&&(e.alternate=null,of(t)),e.child=null,e.deletions=null,e.sibling=null,e.tag===5&&(t=e.stateNode,t!==null&&(delete t[Jt],delete t[rs],delete t[Ya],delete t[zg],delete t[Fg])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function af(e){return e.tag===5||e.tag===3||e.tag===4}function lf(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||af(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Ol(e,t,i){var o=e.tag;if(o===5||o===6)e=e.stateNode,t?i.nodeType===8?i.parentNode.insertBefore(e,t):i.insertBefore(e,t):(i.nodeType===8?(t=i.parentNode,t.insertBefore(e,i)):(t=i,t.appendChild(e)),i=i._reactRootContainer,i!=null||t.onclick!==null||(t.onclick=ao));else if(o!==4&&(e=e.child,e!==null))for(Ol(e,t,i),e=e.sibling;e!==null;)Ol(e,t,i),e=e.sibling}function Dl(e,t,i){var o=e.tag;if(o===5||o===6)e=e.stateNode,t?i.insertBefore(e,t):i.appendChild(e);else if(o!==4&&(e=e.child,e!==null))for(Dl(e,t,i),e=e.sibling;e!==null;)Dl(e,t,i),e=e.sibling}var st=null,Vt=!1;function Rr(e,t,i){for(i=i.child;i!==null;)uf(e,t,i),i=i.sibling}function uf(e,t,i){if(Qt&&typeof Qt.onCommitFiberUnmount=="function")try{Qt.onCommitFiberUnmount(Vs,i)}catch{}switch(i.tag){case 5:ct||qn(i,t);case 6:var o=st,l=Vt;st=null,Rr(e,t,i),st=o,Vt=l,st!==null&&(Vt?(e=st,i=i.stateNode,e.nodeType===8?e.parentNode.removeChild(i):e.removeChild(i)):st.removeChild(i.stateNode));break;case 18:st!==null&&(Vt?(e=st,i=i.stateNode,e.nodeType===8?Xa(e.parentNode,i):e.nodeType===1&&Xa(e,i),Hi(e)):Xa(st,i.stateNode));break;case 4:o=st,l=Vt,st=i.stateNode.containerInfo,Vt=!0,Rr(e,t,i),st=o,Vt=l;break;case 0:case 11:case 14:case 15:if(!ct&&(o=i.updateQueue,o!==null&&(o=o.lastEffect,o!==null))){l=o=o.next;do{var u=l,h=u.destroy;u=u.tag,h!==void 0&&((u&2)!==0||(u&4)!==0)&&Ml(i,t,h),l=l.next}while(l!==o)}Rr(e,t,i);break;case 1:if(!ct&&(qn(i,t),o=i.stateNode,typeof o.componentWillUnmount=="function"))try{o.props=i.memoizedProps,o.state=i.memoizedState,o.componentWillUnmount()}catch(m){Ve(i,t,m)}Rr(e,t,i);break;case 21:Rr(e,t,i);break;case 22:i.mode&1?(ct=(o=ct)||i.memoizedState!==null,Rr(e,t,i),ct=o):Rr(e,t,i);break;default:Rr(e,t,i)}}function cf(e){var t=e.updateQueue;if(t!==null){e.updateQueue=null;var i=e.stateNode;i===null&&(i=e.stateNode=new rm),t.forEach(function(o){var l=fm.bind(null,e,o);i.has(o)||(i.add(o),o.then(l,l))})}}function qt(e,t){var i=t.deletions;if(i!==null)for(var o=0;ol&&(l=h),o&=~u}if(o=l,o=qe()-o,o=(120>o?120:480>o?480:1080>o?1080:1920>o?1920:3e3>o?3e3:4320>o?4320:1960*sm(o/1960))-o,10e?16:e,Pr===null)var o=!1;else{if(e=Pr,Pr=null,jo=0,(be&6)!==0)throw Error(s(331));var l=be;for(be|=4,X=e.current;X!==null;){var u=X,h=u.child;if((X.flags&16)!==0){var m=u.deletions;if(m!==null){for(var _=0;_qe()-$l?Zr(e,0):Fl|=i),yt(e,t)}function If(e,t){t===0&&((e.mode&1)===0?t=1:(t=Hs,Hs<<=1,(Hs&130023424)===0&&(Hs=4194304)));var i=ft();e=ar(e,t),e!==null&&(Fi(e,t,i),yt(e,i))}function dm(e){var t=e.memoizedState,i=0;t!==null&&(i=t.retryLane),If(e,i)}function fm(e,t){var i=0;switch(e.tag){case 13:var o=e.stateNode,l=e.memoizedState;l!==null&&(i=l.retryLane);break;case 19:o=e.stateNode;break;default:throw Error(s(314))}o!==null&&o.delete(t),If(e,i)}var kf;kf=function(e,t,i){if(e!==null)if(e.memoizedProps!==t.pendingProps||ht.current)gt=!0;else{if((e.lanes&i)===0&&(t.flags&128)===0)return gt=!1,Zg(e,t,i);gt=(e.flags&131072)!==0}else gt=!1,De&&(t.flags&1048576)!==0&&rd(t,po,t.index);switch(t.lanes=0,t.tag){case 2:var o=t.type;Uo(e,t),e=t.pendingProps;var l=Mn(t,at.current);$n(t,i),l=wl(null,t,o,e,l,i);var u=vl();return t.flags|=1,typeof l=="object"&&l!==null&&typeof l.render=="function"&&l.$$typeof===void 0?(t.tag=1,t.memoizedState=null,t.updateQueue=null,pt(o)?(u=!0,co(t)):u=!1,t.memoizedState=l.state!==null&&l.state!==void 0?l.state:null,dl(t),l.updater=To,t.stateNode=l,l._reactInternals=t,bl(t,o,e,i),t=Ul(null,t,o,!0,u,i)):(t.tag=0,De&&u&&tl(t),dt(null,t,l,i),t=t.child),t;case 16:o=t.elementType;e:{switch(Uo(e,t),e=t.pendingProps,l=o._init,o=l(o._payload),t.type=o,l=t.tag=pm(o),e=Lt(o,e),l){case 0:t=El(null,t,o,e,i);break e;case 1:t=Jd(null,t,o,e,i);break e;case 11:t=qd(null,t,o,e,i);break e;case 14:t=Hd(null,t,o,Lt(o.type,e),i);break e}throw Error(s(306,o,""))}return t;case 0:return o=t.type,l=t.pendingProps,l=t.elementType===o?l:Lt(o,l),El(e,t,o,l,i);case 1:return o=t.type,l=t.pendingProps,l=t.elementType===o?l:Lt(o,l),Jd(e,t,o,l,i);case 3:e:{if(Gd(t),e===null)throw Error(s(387));o=t.pendingProps,u=t.memoizedState,l=u.element,dd(e,t),_o(t,o,null,i);var h=t.memoizedState;if(o=h.element,u.isDehydrated)if(u={element:o,isDehydrated:!1,cache:h.cache,pendingSuspenseBoundaries:h.pendingSuspenseBoundaries,transitions:h.transitions},t.updateQueue.baseState=u,t.memoizedState=u,t.flags&256){l=Vn(Error(s(423)),t),t=Xd(e,t,o,i,l);break e}else if(o!==l){l=Vn(Error(s(424)),t),t=Xd(e,t,o,i,l);break e}else for(bt=kr(t.stateNode.containerInfo.firstChild),kt=t,De=!0,$t=null,i=ud(t,null,o,i),t.child=i;i;)i.flags=i.flags&-3|4096,i=i.sibling;else{if(Dn(),o===l){t=ur(e,t,i);break e}dt(e,t,o,i)}t=t.child}return t;case 5:return pd(t),e===null&&il(t),o=t.type,l=t.pendingProps,u=e!==null?e.memoizedProps:null,h=l.children,Ja(o,l)?h=null:u!==null&&Ja(o,u)&&(t.flags|=32),Qd(e,t),dt(e,t,h,i),t.child;case 6:return e===null&&il(t),null;case 13:return Yd(e,t,i);case 4:return fl(t,t.stateNode.containerInfo),o=t.pendingProps,e===null?t.child=zn(t,null,o,i):dt(e,t,o,i),t.child;case 11:return o=t.type,l=t.pendingProps,l=t.elementType===o?l:Lt(o,l),qd(e,t,o,l,i);case 7:return dt(e,t,t.pendingProps,i),t.child;case 8:return dt(e,t,t.pendingProps.children,i),t.child;case 12:return dt(e,t,t.pendingProps.children,i),t.child;case 10:e:{if(o=t.type._context,l=t.pendingProps,u=t.memoizedProps,h=l.value,Ae(yo,o._currentValue),o._currentValue=h,u!==null)if(Ft(u.value,h)){if(u.children===l.children&&!ht.current){t=ur(e,t,i);break e}}else for(u=t.child,u!==null&&(u.return=t);u!==null;){var m=u.dependencies;if(m!==null){h=u.child;for(var _=m.firstContext;_!==null;){if(_.context===o){if(u.tag===1){_=lr(-1,i&-i),_.tag=2;var C=u.updateQueue;if(C!==null){C=C.shared;var F=C.pending;F===null?_.next=_:(_.next=F.next,F.next=_),C.pending=_}}u.lanes|=i,_=u.alternate,_!==null&&(_.lanes|=i),ul(u.return,i,t),m.lanes|=i;break}_=_.next}}else if(u.tag===10)h=u.type===t.type?null:u.child;else if(u.tag===18){if(h=u.return,h===null)throw Error(s(341));h.lanes|=i,m=h.alternate,m!==null&&(m.lanes|=i),ul(h,i,t),h=u.sibling}else h=u.child;if(h!==null)h.return=u;else for(h=u;h!==null;){if(h===t){h=null;break}if(u=h.sibling,u!==null){u.return=h.return,h=u;break}h=h.return}u=h}dt(e,t,l.children,i),t=t.child}return t;case 9:return l=t.type,o=t.pendingProps.children,$n(t,i),l=Nt(l),o=o(l),t.flags|=1,dt(e,t,o,i),t.child;case 14:return o=t.type,l=Lt(o,t.pendingProps),l=Lt(o.type,l),Hd(e,t,o,l,i);case 15:return Kd(e,t,t.type,t.pendingProps,i);case 17:return o=t.type,l=t.pendingProps,l=t.elementType===o?l:Lt(o,l),Uo(e,t),t.tag=1,pt(o)?(e=!0,co(t)):e=!1,$n(t,i),Od(t,o,l),bl(t,o,l,i),Ul(null,t,o,!0,e,i);case 19:return ef(e,t,i);case 22:return Wd(e,t,i)}throw Error(s(156,t.tag))};function bf(e,t){return nc(e,t)}function hm(e,t,i,o){this.tag=e,this.key=i,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=o,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function At(e,t,i,o){return new hm(e,t,i,o)}function Jl(e){return e=e.prototype,!(!e||!e.isReactComponent)}function pm(e){if(typeof e=="function")return Jl(e)?1:0;if(e!=null){if(e=e.$$typeof,e===Le)return 11;if(e===ke)return 14}return 2}function Mr(e,t){var i=e.alternate;return i===null?(i=At(e.tag,t,e.key,e.mode),i.elementType=e.elementType,i.type=e.type,i.stateNode=e.stateNode,i.alternate=e,e.alternate=i):(i.pendingProps=t,i.type=e.type,i.flags=0,i.subtreeFlags=0,i.deletions=null),i.flags=e.flags&14680064,i.childLanes=e.childLanes,i.lanes=e.lanes,i.child=e.child,i.memoizedProps=e.memoizedProps,i.memoizedState=e.memoizedState,i.updateQueue=e.updateQueue,t=e.dependencies,i.dependencies=t===null?null:{lanes:t.lanes,firstContext:t.firstContext},i.sibling=e.sibling,i.index=e.index,i.ref=e.ref,i}function Fo(e,t,i,o,l,u){var h=2;if(o=e,typeof e=="function")Jl(e)&&(h=1);else if(typeof e=="string")h=5;else e:switch(e){case ge:return tn(i.children,l,u,t);case me:h=8,l|=8;break;case ue:return e=At(12,i,t,l|2),e.elementType=ue,e.lanes=u,e;case Me:return e=At(13,i,t,l),e.elementType=Me,e.lanes=u,e;case it:return e=At(19,i,t,l),e.elementType=it,e.lanes=u,e;case W:return $o(i,l,u,t);default:if(typeof e=="object"&&e!==null)switch(e.$$typeof){case Re:h=10;break e;case We:h=9;break e;case Le:h=11;break e;case ke:h=14;break e;case P:h=16,o=null;break e}throw Error(s(130,e==null?e:typeof e,""))}return t=At(h,i,t,l),t.elementType=e,t.type=o,t.lanes=u,t}function tn(e,t,i,o){return e=At(7,e,o,t),e.lanes=i,e}function $o(e,t,i,o){return e=At(22,e,o,t),e.elementType=W,e.lanes=i,e.stateNode={isHidden:!1},e}function Gl(e,t,i){return e=At(6,e,null,t),e.lanes=i,e}function Xl(e,t,i){return t=At(4,e.children!==null?e.children:[],e.key,t),t.lanes=i,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function gm(e,t,i,o,l){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=ka(0),this.expirationTimes=ka(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=ka(0),this.identifierPrefix=o,this.onRecoverableError=l,this.mutableSourceEagerHydrationData=null}function Yl(e,t,i,o,l,u,h,m,_){return e=new gm(e,t,i,m,_),t===1?(t=1,u===!0&&(t|=8)):t=0,u=At(3,null,null,t),e.current=u,u.stateNode=e,u.memoizedState={element:o,isDehydrated:i,cache:null,transitions:null,pendingSuspenseBoundaries:null},dl(u),e}function mm(e,t,i){var o=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(r)}catch(n){console.error(n)}}return r(),iu.exports=Tm(),iu.exports}var zf;function Um(){if(zf)return Qo;zf=1;var r=Em();return Qo.createRoot=r.createRoot,Qo.hydrateRoot=r.hydrateRoot,Qo}var Rm=Um(),vs={},Ff;function Nm(){if(Ff)return vs;Ff=1,vs.byteLength=v,vs.toByteArray=x,vs.fromByteArray=j;for(var r=[],n=[],s=typeof Uint8Array<"u"?Uint8Array:Array,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",c=0,f=a.length;c0)throw new Error("Invalid string. Length must be a multiple of 4");var Q=O.indexOf("=");Q===-1&&(Q=q);var $=Q===q?0:4-Q%4;return[Q,$]}function v(O){var q=p(O),Q=q[0],$=q[1];return(Q+$)*3/4-$}function y(O,q,Q){return(q+Q)*3/4-Q}function x(O){var q,Q=p(O),$=Q[0],fe=Q[1],T=new s(y(O,$,fe)),A=0,L=fe>0?$-4:$,J;for(J=0;J>16&255,T[A++]=q>>8&255,T[A++]=q&255;return fe===2&&(q=n[O.charCodeAt(J)]<<2|n[O.charCodeAt(J+1)]>>4,T[A++]=q&255),fe===1&&(q=n[O.charCodeAt(J)]<<10|n[O.charCodeAt(J+1)]<<4|n[O.charCodeAt(J+2)]>>2,T[A++]=q>>8&255,T[A++]=q&255),T}function R(O){return r[O>>18&63]+r[O>>12&63]+r[O>>6&63]+r[O&63]}function N(O,q,Q){for(var $,fe=[],T=q;TL?L:A+T));return $===1?(q=O[Q-1],fe.push(r[q>>2]+r[q<<4&63]+"==")):$===2&&(q=(O[Q-2]<<8)+O[Q-1],fe.push(r[q>>10]+r[q>>4&63]+r[q<<2&63]+"=")),fe.join("")}return vs}var Mu=Nm(),Jo={exports:{}},$f;function Pm(){return $f||($f=1,(function(r,n){const{hasOwnProperty:s}=Object.prototype,a=fe();a.configure=fe,a.stringify=a,a.default=a,n.stringify=a,n.configure=fe,r.exports=a;const c=/[\u0000-\u001f\u0022\u005c\ud800-\udfff]/;function f(T){return T.length<5e3&&!c.test(T)?`"${T}"`:JSON.stringify(T)}function p(T,A){if(T.length>200||A)return T.sort(A);for(let L=1;LJ;)T[Y]=T[Y-1],Y--;T[Y]=J}return T}const v=Object.getOwnPropertyDescriptor(Object.getPrototypeOf(Object.getPrototypeOf(new Int8Array)),Symbol.toStringTag).get;function y(T){return v.call(T)!==void 0&&T.length!==0}function x(T,A,L){T.length= 1`)}return L===void 0?1/0:L}function q(T){return T===1?"1 item":`${T} items`}function Q(T){const A=new Set;for(const L of T)(typeof L=="string"||typeof L=="number")&&A.add(String(L));return A}function $(T){if(s.call(T,"strict")){const A=T.strict;if(typeof A!="boolean")throw new TypeError('The "strict" argument must be of type boolean');if(A)return L=>{let J=`Object can not safely be stringified. Received type ${typeof L}`;throw typeof L!="function"&&(J+=` (${L.toString()})`),new Error(J)}}}function fe(T){T={...T};const A=$(T);A&&(T.bigint===void 0&&(T.bigint=!1),"circularValue"in T||(T.circularValue=Error));const L=R(T),J=j(T,"bigint"),Y=N(T),ge=typeof Y=="function"?Y:void 0,me=O(T,"maximumDepth"),ue=O(T,"maximumBreadth");function Re(ke,P,W,M,H,z){let w=P[ke];switch(typeof w=="object"&&w!==null&&typeof w.toJSON=="function"&&(w=w.toJSON(ke)),w=M.call(P,ke,w),typeof w){case"string":return f(w);case"object":{if(w===null)return"null";if(W.indexOf(w)!==-1)return L;let E="",ee=",";const ne=z;if(Array.isArray(w)){if(w.length===0)return"[]";if(meue){const Dt=w.length-ue-1;E+=`${ee}"... ${q(Dt)} not stringified"`}return H!==""&&(E+=` +${ne}`),W.pop(),`[${E}]`}let te=Object.keys(w);const le=te.length;if(le===0)return"{}";if(meue){const _e=le-ue;E+=`${he}"...":${ie}"${q(_e)} not stringified"`,he=ee}return H!==""&&he.length>1&&(E=` +${z}${E} +${ne}`),W.pop(),`{${E}}`}case"number":return isFinite(w)?String(w):A?A(w):"null";case"boolean":return w===!0?"true":"false";case"undefined":return;case"bigint":if(J)return String(w);default:return A?A(w):void 0}}function We(ke,P,W,M,H,z){switch(typeof P=="object"&&P!==null&&typeof P.toJSON=="function"&&(P=P.toJSON(ke)),typeof P){case"string":return f(P);case"object":{if(P===null)return"null";if(W.indexOf(P)!==-1)return L;const w=z;let E="",ee=",";if(Array.isArray(P)){if(P.length===0)return"[]";if(meue){const we=P.length-ue-1;E+=`${ee}"... ${q(we)} not stringified"`}return H!==""&&(E+=` +${w}`),W.pop(),`[${E}]`}W.push(P);let ne="";H!==""&&(z+=H,ee=`, +${z}`,ne=" ");let te="";for(const le of M){const ie=We(le,P[le],W,M,H,z);ie!==void 0&&(E+=`${te}${f(le)}:${ne}${ie}`,te=ee)}return H!==""&&te.length>1&&(E=` +${z}${E} +${w}`),W.pop(),`{${E}}`}case"number":return isFinite(P)?String(P):A?A(P):"null";case"boolean":return P===!0?"true":"false";case"undefined":return;case"bigint":if(J)return String(P);default:return A?A(P):void 0}}function Le(ke,P,W,M,H){switch(typeof P){case"string":return f(P);case"object":{if(P===null)return"null";if(typeof P.toJSON=="function"){if(P=P.toJSON(ke),typeof P!="object")return Le(ke,P,W,M,H);if(P===null)return"null"}if(W.indexOf(P)!==-1)return L;const z=H;if(Array.isArray(P)){if(P.length===0)return"[]";if(meue){const Ge=P.length-ue-1;ie+=`${he}"... ${q(Ge)} not stringified"`}return ie+=` +${z}`,W.pop(),`[${ie}]`}let w=Object.keys(P);const E=w.length;if(E===0)return"{}";if(meue){const ie=E-ue;ne+=`${te}"...": "${q(ie)} not stringified"`,te=ee}return te!==""&&(ne=` +${H}${ne} +${z}`),W.pop(),`{${ne}}`}case"number":return isFinite(P)?String(P):A?A(P):"null";case"boolean":return P===!0?"true":"false";case"undefined":return;case"bigint":if(J)return String(P);default:return A?A(P):void 0}}function Me(ke,P,W){switch(typeof P){case"string":return f(P);case"object":{if(P===null)return"null";if(typeof P.toJSON=="function"){if(P=P.toJSON(ke),typeof P!="object")return Me(ke,P,W);if(P===null)return"null"}if(W.indexOf(P)!==-1)return L;let M="";const H=P.length!==void 0;if(H&&Array.isArray(P)){if(P.length===0)return"[]";if(meue){const ie=P.length-ue-1;M+=`,"... ${q(ie)} not stringified"`}return W.pop(),`[${M}]`}let z=Object.keys(P);const w=z.length;if(w===0)return"{}";if(meue){const ne=w-ue;M+=`${E}"...":"${q(ne)} not stringified"`}return W.pop(),`{${M}}`}case"number":return isFinite(P)?String(P):A?A(P):"null";case"boolean":return P===!0?"true":"false";case"undefined":return;case"bigint":if(J)return String(P);default:return A?A(P):void 0}}function it(ke,P,W){if(arguments.length>1){let M="";if(typeof W=="number"?M=" ".repeat(Math.min(W,10)):typeof W=="string"&&(M=W.slice(0,10)),P!=null){if(typeof P=="function")return Re("",{"":ke},[],P,M,"");if(Array.isArray(P))return We("",ke,[],Q(P),M,"")}if(M.length!==0)return Le("",ke,[],M,"")}return Me("",ke,[])}return it}})(Jo,Jo.exports)),Jo.exports}var Bm=Pm();const wh=yh(Bm);wh.configure;const Lf=wh;var bi=class Yo{__time_duration_micros__;static MICROS_PER_MILLIS=1000n;static getAlgebraicType(){return oe.Product({elements:[{name:"__time_duration_micros__",algebraicType:oe.I64}]})}static isTimeDuration(n){if(n.tag!=="Product")return!1;const s=n.value.elements;if(s.length!==1)return!1;const a=s[0];return a.name==="__time_duration_micros__"&&a.algebraicType.tag==="I64"}get micros(){return this.__time_duration_micros__}get millis(){return Number(this.micros/Yo.MICROS_PER_MILLIS)}constructor(n){this.__time_duration_micros__=n}static fromMillis(n){return new Yo(BigInt(n)*Yo.MICROS_PER_MILLIS)}toString(){const n=this.micros,s=n<0?"-":"+",a=n<0?-n:n,c=a/1000000n,f=a%1000000n;return`${s}${c}.${String(f).padStart(6,"0")}`}},Ci=class rn{__timestamp_micros_since_unix_epoch__;static MICROS_PER_MILLIS=1000n;get microsSinceUnixEpoch(){return this.__timestamp_micros_since_unix_epoch__}constructor(n){this.__timestamp_micros_since_unix_epoch__=n}static getAlgebraicType(){return oe.Product({elements:[{name:"__timestamp_micros_since_unix_epoch__",algebraicType:oe.I64}]})}static isTimestamp(n){if(n.tag!=="Product")return!1;const s=n.value.elements;if(s.length!==1)return!1;const a=s[0];return a.name==="__timestamp_micros_since_unix_epoch__"&&a.algebraicType.tag==="I64"}static UNIX_EPOCH=new rn(0n);static now(){return rn.fromDate(new Date)}toMillis(){return this.microsSinceUnixEpoch/1000n}static fromDate(n){const s=n.getTime(),a=BigInt(s)*rn.MICROS_PER_MILLIS;return new rn(a)}toDate(){const s=this.__timestamp_micros_since_unix_epoch__/rn.MICROS_PER_MILLIS;if(s>BigInt(Number.MAX_SAFE_INTEGER)||sBigInt(Number.MAX_SAFE_INTEGER)||svt.MAX_UUID_BIGINT)throw new Error("Invalid UUID: must be between 0 and `MAX_UUID_BIGINT`");this.__uuid__=n}static fromRandomBytesV4(n){if(n.length!==16)throw new Error("UUID v4 requires 16 bytes");const s=new Uint8Array(n);return s[6]=s[6]&15|64,s[8]=s[8]&63|128,new vt(vt.bytesToBigInt(s))}static fromCounterV7(n,s,a){if(a.length!==4)throw new Error("`fromCounterV7` requires `randomBytes.length == 4`");if(n.value<0)throw new Error("`fromCounterV7` uuid `counter` must be non-negative");if(s.__timestamp_micros_since_unix_epoch__<0)throw new Error("`fromCounterV7` `timestamp` before unix epoch");const c=n.value;n.value=c+1&2147483647;const f=s.toMillis()&0xffffffffffffn,p=new Uint8Array(16);return p[0]=Number(f>>40n&0xffn),p[1]=Number(f>>32n&0xffn),p[2]=Number(f>>24n&0xffn),p[3]=Number(f>>16n&0xffn),p[4]=Number(f>>8n&0xffn),p[5]=Number(f&0xffn),p[7]=c>>>23&255,p[9]=c>>>15&255,p[10]=c>>>7&255,p[11]=(c&127)<<1&255,p[12]|=a[0]&127,p[13]=a[1],p[14]=a[2],p[15]=a[3],p[6]=p[6]&15|112,p[8]=p[8]&63|128,new vt(vt.bytesToBigInt(p))}static parse(n){const s=n.replace(/-/g,"");if(s.length!==32)throw new Error("Invalid hex UUID");let a=0n;for(let c=0;c<32;c+=2)a=a<<8n|BigInt(parseInt(s.slice(c,c+2),16));return new vt(a)}toString(){const s=[...vt.bigIntToBytes(this.__uuid__)].map(a=>a.toString(16).padStart(2,"0")).join("");return s.slice(0,8)+"-"+s.slice(8,12)+"-"+s.slice(12,16)+"-"+s.slice(16,20)+"-"+s.slice(20)}asBigInt(){return this.__uuid__}toBytes(){return vt.bigIntToBytes(this.__uuid__)}static bytesToBigInt(n){let s=0n;for(const a of n)s=s<<8n|BigInt(a);return s}static bigIntToBytes(n){const s=new Uint8Array(16);for(let a=15;a>=0;a--)s[a]=Number(n&0xffn),n>>=8n;return s}getVersion(){const n=this.toBytes()[6]>>4&15;switch(n){case 4:return"V4";case 7:return"V7";default:if(this==vt.NIL)return"Nil";if(this==vt.MAX)return"Max";throw new Error(`Unsupported UUID version: ${n}`)}}getCounter(){const n=this.toBytes(),s=n[7],a=n[9],c=n[10],f=n[11]>>>1;return s<<23|a<<15|c<<7|f|0}compareTo(n){return this.__uuid__n.__uuid__?1:0}static getAlgebraicType(){return oe.Product({elements:[{name:"__uuid__",algebraicType:oe.U128}]})}},ze=class{view;offset=0;constructor(n){this.view=n instanceof DataView?n:new DataView(n.buffer,n.byteOffset,n.byteLength),this.offset=0}reset(n){this.view=n,this.offset=0}get remaining(){return this.view.byteLength-this.offset}#e(n){if(this.offset+n>this.view.byteLength)throw new RangeError(`Tried to read ${n} byte(s) at relative offset ${this.offset}, but only ${this.remaining} byte(s) remain`)}readUInt8Array(){const n=this.readU32();return this.#e(n),this.readBytes(n)}readBool(){const n=this.view.getUint8(this.offset);return this.offset+=1,n!==0}readByte(){const n=this.view.getUint8(this.offset);return this.offset+=1,n}readBytes(n){const s=new Uint8Array(this.view.buffer,this.view.byteOffset+this.offset,n);return this.offset+=n,s}readI8(){const n=this.view.getInt8(this.offset);return this.offset+=1,n}readU8(){return this.readByte()}readI16(){const n=this.view.getInt16(this.offset,!0);return this.offset+=2,n}readU16(){const n=this.view.getUint16(this.offset,!0);return this.offset+=2,n}readI32(){const n=this.view.getInt32(this.offset,!0);return this.offset+=4,n}readU32(){const n=this.view.getUint32(this.offset,!0);return this.offset+=4,n}readI64(){const n=this.view.getBigInt64(this.offset,!0);return this.offset+=8,n}readU64(){const n=this.view.getBigUint64(this.offset,!0);return this.offset+=8,n}readU128(){const n=this.view.getBigUint64(this.offset,!0),s=this.view.getBigUint64(this.offset+8,!0);return this.offset+=16,(s<>BigInt(64);this.view.setBigUint64(this.offset,s,!0),this.view.setBigUint64(this.offset+8,a,!0),this.offset+=16}writeI128(n){this.expandBuffer(16);const s=n&BigInt("0xFFFFFFFFFFFFFFFF"),a=n>>BigInt(64);this.view.setBigInt64(this.offset,s,!0),this.view.setBigInt64(this.offset+8,a,!0),this.offset+=16}writeU256(n){this.expandBuffer(32);const s=BigInt("0xFFFFFFFFFFFFFFFF"),a=n&s,c=n>>BigInt(64)&s,f=n>>BigInt(128)&s,p=n>>BigInt(192);this.view.setBigUint64(this.offset+0,a,!0),this.view.setBigUint64(this.offset+8,c,!0),this.view.setBigUint64(this.offset+16,f,!0),this.view.setBigUint64(this.offset+24,p,!0),this.offset+=32}writeI256(n){this.expandBuffer(32);const s=BigInt("0xFFFFFFFFFFFFFFFF"),a=n&s,c=n>>BigInt(64)&s,f=n>>BigInt(128)&s,p=n>>BigInt(192);this.view.setBigUint64(this.offset+0,a,!0),this.view.setBigUint64(this.offset+8,c,!0),this.view.setBigUint64(this.offset+16,f,!0),this.view.setBigInt64(this.offset+24,p,!0),this.offset+=32}writeF32(n){this.expandBuffer(4),this.view.setFloat32(this.offset,n,!0),this.offset+=4}writeF64(n){this.expandBuffer(8),this.view.setFloat64(this.offset,n,!0),this.offset+=8}writeString(n){const a=new TextEncoder().encode(n);this.writeUInt8Array(a)}};function Is(r,n){if(r===n)return!0;if(typeof r!="object"||r===null||typeof n!="object"||n===null)return!1;const s=Object.keys(r),a=Object.keys(n);if(s.length!==a.length)return!1;for(const c of s)if(!a.includes(c)||!Is(r[c],n[c]))return!1;return!0}function _h(r){return Array.prototype.map.call(r.reverse(),n=>("00"+n.toString(16)).slice(-2)).join("")}function jm(r){if(r.length!=16)throw new Error(`Uint8Array is not 16 bytes long: ${r}`);return new ze(r).readU128()}function Om(r){if(r.length!=32)throw new Error(`Uint8Array is not 32 bytes long: [${r}]`);return new ze(r).readU256()}function Sh(r){r.startsWith("0x")&&(r=r.slice(2));const n=r.match(/.{1,2}/g)||[];return Uint8Array.from(n.map(a=>parseInt(a,16))).reverse()}function Dm(r){return jm(Sh(r))}function zm(r){return Om(Sh(r))}function xh(r){const n=new Pe(16);return n.writeU128(r),n.getBuffer()}function Ih(r){return _h(xh(r))}function kh(r){const n=new Pe(32);return n.writeU256(r),n.getBuffer()}function bh(r){return _h(kh(r))}function Fm(r){const n=Ch(r);return n.charAt(0).toUpperCase()+n.slice(1)}function Ch(r){const n=r.replace(/[-_]+/g,"_").replace(/_([a-zA-Z0-9])/g,(s,a)=>a.toUpperCase());return n.charAt(0).toLowerCase()+n.slice(1)}var Vf=Object.hasOwn,Bs=class fu{__identity__;constructor(n){this.__identity__=typeof n=="string"?zm(n):n}static getAlgebraicType(){return oe.Product({elements:[{name:"__identity__",algebraicType:oe.U256}]})}isEqual(n){return this.toHexString()===n.toHexString()}equals(n){return this.isEqual(n)}toHexString(){return bh(this.__identity__)}toUint8Array(){return kh(this.__identity__)}static fromString(n){return new fu(n)}static zero(){return new fu(0n)}toString(){return this.toHexString()}},bs=new Map,Cs=new Map,oe={Ref:r=>({tag:"Ref",value:r}),Sum:r=>({tag:"Sum",value:r}),Product:r=>({tag:"Product",value:r}),Array:r=>({tag:"Array",value:r}),String:{tag:"String"},Bool:{tag:"Bool"},I8:{tag:"I8"},U8:{tag:"U8"},I16:{tag:"I16"},U16:{tag:"U16"},I32:{tag:"I32"},U32:{tag:"U32"},I64:{tag:"I64"},U64:{tag:"U64"},I128:{tag:"I128"},U128:{tag:"U128"},I256:{tag:"I256"},U256:{tag:"U256"},F32:{tag:"F32"},F64:{tag:"F64"},makeSerializer(r,n){if(r.tag==="Ref"){if(!n)throw new Error("cannot serialize refs without a typespace");for(;r.tag==="Ref";)r=n.types[r.value]}switch(r.tag){case"Product":return pr.makeSerializer(r.value,n);case"Sum":return ua.makeSerializer(r.value,n);case"Array":if(r.value.tag==="U8")return $m;{const s=oe.makeSerializer(r.value,n);return(a,c)=>{a.writeU32(c.length);for(const f of c)s(a,f)}}default:return Th[r.tag]}},serializeValue(r,n,s,a){oe.makeSerializer(n,a)(r,s)},makeDeserializer(r,n){if(r.tag==="Ref"){if(!n)throw new Error("cannot deserialize refs without a typespace");for(;r.tag==="Ref";)r=n.types[r.value]}switch(r.tag){case"Product":return pr.makeDeserializer(r.value,n);case"Sum":return ua.makeDeserializer(r.value,n);case"Array":if(r.value.tag==="U8")return Lm;{const s=oe.makeDeserializer(r.value,n);return a=>{const c=a.readU32(),f=Array(c);for(let p=0;pr.elements.every(({algebraicType:n})=>Vm.has(n.tag)),qm=r=>r.elements.reduce((n,{algebraicType:s})=>n+xi[s.tag],0),Go={Bool:"Uint8",I8:"Int8",U8:"Uint8",I16:"Int16",U16:"Uint16",I32:"Int32",U32:"Uint32",I64:"BigInt64",U64:"BigUint64",F32:"Float32",F64:"Float64"},Zo={__time_duration_micros__:r=>new bi(r.readI64()),__timestamp_micros_since_unix_epoch__:r=>new Ci(r.readI64()),__identity__:r=>new Bs(r.readU256()),__connection_id__:r=>new ga(r.readU128()),__uuid__:r=>new vh(r.readU128())};Object.freeze(Zo);var Hm=()=>({}),Hf=r=>{let n;switch(r.algebraicType.tag){case"String":n="''";break;case"Bool":n="false";break;case"I8":case"U8":case"I16":case"U16":case"I32":case"U32":n="0";break;case"I64":case"U64":case"I128":case"U128":case"I256":case"U256":n="0n";break;case"F32":case"F64":n="0.0";break;default:n="undefined"}return`${r.name}: ${n}`},pr={makeSerializer(r,n){let s=bs.get(r);if(s!=null)return s;if(qf(r)){const p=`"use strict"; +writer.expandBuffer(${qm(r)}); +const view = writer.view; +${r.elements.map(({name:v,algebraicType:{tag:y}})=>y in Go?`view.set${Go[y]}(writer.offset, value.${v}, ${xi[y]>1?"true":""}); +writer.offset += ${xi[y]};`:`writer.write${y}(value.${v});`).join(` +`)}`;return s=Function("writer","value",p),bs.set(r,s),s}const a={},c=`"use strict"; +`+r.elements.map(f=>`this.${f.name}(writer, value.${f.name});`).join(` +`);s=Function("writer","value",c).bind(a),bs.set(r,s);for(const{name:f,algebraicType:p}of r.elements)a[f]=oe.makeSerializer(p,n);return Object.freeze(a),s},serializeValue(r,n,s,a){pr.makeSerializer(n,a)(r,s)},makeDeserializer(r,n){switch(r.elements.length){case 0:return Hm;case 1:{const c=r.elements[0].name;if(Vf(Zo,c))return Zo[c]}}let s=Cs.get(r);if(s!=null)return s;if(qf(r)){const c=`"use strict"; +const result = { ${r.elements.map(Hf).join(", ")} }; +const view = reader.view; +${r.elements.map(({name:f,algebraicType:{tag:p}})=>p in Go?p==="Bool"?`result.${f} = view.getUint8(reader.offset) !== 0; +reader.offset += 1;`:`result.${f} = view.get${Go[p]}(reader.offset, ${xi[p]>1?"true":""}); +reader.offset += ${xi[p]};`:`result.${f} = reader.read${p}();`).join(` +`)} +return result;`;return s=Function("reader",c),Cs.set(r,s),s}const a={};s=Function("reader",`"use strict"; +const result = { ${r.elements.map(Hf).join(", ")} }; +${r.elements.map(({name:c})=>`result.${c} = this.${c}(reader);`).join(` +`)} +return result;`).bind(a),Cs.set(r,s);for(const{name:c,algebraicType:f}of r.elements)a[c]=oe.makeDeserializer(f,n);return Object.freeze(a),s},deserializeValue(r,n,s){return pr.makeDeserializer(n,s)(r)},intoMapKey(r,n){if(r.elements.length===1){const a=r.elements[0].name;if(Vf(Zo,a))return n[a]}const s=new Pe(10);return oe.serializeValue(s,oe.Product(r),n),s.toBase64()}},ua={makeSerializer(r,n){if(r.variants.length==2&&r.variants[0].name==="some"&&r.variants[1].name==="none"){const s=oe.makeSerializer(r.variants[0].algebraicType,n);return(a,c)=>{c!=null?(a.writeByte(0),s(a,c)):a.writeByte(1)}}else if(r.variants.length==2&&r.variants[0].name==="ok"&&r.variants[1].name==="err"){const s=oe.makeSerializer(r.variants[0].algebraicType,n),a=oe.makeSerializer(r.variants[0].algebraicType,n);return(c,f)=>{if("ok"in f)c.writeU8(0),s(c,f.ok);else if("err"in f)c.writeU8(1),a(c,f.err);else throw new TypeError("could not serialize result: object had neither a `ok` nor an `err` field")}}else{let s=bs.get(r);if(s!=null)return s;const a={},c=`switch (value.tag) { +${r.variants.map(({name:f},p)=>` case ${JSON.stringify(f)}: + writer.writeByte(${p}); + return this.${f}(writer, value.value);`).join(` +`)} + default: + throw new TypeError( + \`Could not serialize sum type; unknown tag \${value.tag}\` + ) +} +`;s=Function("writer","value",c).bind(a),bs.set(r,s);for(const{name:f,algebraicType:p}of r.variants)a[f]=oe.makeSerializer(p,n);return Object.freeze(a),s}},serializeValue(r,n,s,a){ua.makeSerializer(n,a)(r,s)},makeDeserializer(r,n){if(r.variants.length==2&&r.variants[0].name==="some"&&r.variants[1].name==="none"){const s=oe.makeDeserializer(r.variants[0].algebraicType,n);return a=>{const c=a.readU8();if(c===0)return s(a);if(c===1)return;throw`Can't deserialize an option type, couldn't find ${c} tag`}}else if(r.variants.length==2&&r.variants[0].name==="ok"&&r.variants[1].name==="err"){const s=oe.makeDeserializer(r.variants[0].algebraicType,n),a=oe.makeDeserializer(r.variants[1].algebraicType,n);return c=>{const f=c.readByte();if(f===0)return{ok:s(c)};if(f===1)return{err:a(c)};throw`Can't deserialize a result type, couldn't find ${f} tag`}}else{let s=Cs.get(r);if(s!=null)return s;const a={};s=Function("reader",`switch (reader.readU8()) { +${r.variants.map(({name:c},f)=>`case ${f}: return { tag: ${JSON.stringify(c)}, value: this.${c}(reader) };`).join(` +`)} }`).bind(a),Cs.set(r,s);for(const{name:c,algebraicType:f}of r.variants)a[c]=oe.makeDeserializer(f,n);return Object.freeze(a),s}},deserializeValue(r,n,s){return ua.makeDeserializer(n,s)(r)}},ga=class ea{__connection_id__;constructor(n){this.__connection_id__=n}static getAlgebraicType(){return oe.Product({elements:[{name:"__connection_id__",algebraicType:oe.U128}]})}isZero(){return this.__connection_id__===BigInt(0)}static nullIfZero(n){return n.isZero()?null:n}static random(){function n(){return Math.floor(Math.random()*255)}let s=BigInt(0);for(let a=0;a<16;a++)s=s<c.name==="Interval"),a=n.find(c=>c.name==="Time");return!s||!a?!1:bi.isTimeDuration(s.algebraicType)&&Ci.isTimestamp(a.algebraicType)}},Jm=r=>({tag:"Interval",value:new bi(r)}),Gm=r=>({tag:"Time",value:new Ci(r)}),Uh=Qm,Xm={getAlgebraicType(r){return oe.Sum({variants:[{name:"some",algebraicType:r},{name:"none",algebraicType:oe.Product({elements:[]})}]})}},Ym={getAlgebraicType(r,n){return oe.Sum({variants:[{name:"ok",algebraicType:r},{name:"err",algebraicType:n}]})}},ma=Symbol("QueryBrand"),Zm=r=>!!r&&typeof r=="object"&&ma in r;function ey(r){return r.toSql()}var Kf=class Rh{constructor(n,s,a){if(this.sourceQuery=n,this.filterQuery=s,this.joinCondition=a,n.table.sourceName===s.table.sourceName)throw new Error("Cannot semijoin a table to itself")}[ma]=!0;type="semijoin";build(){return this}where(n){const s=this.sourceQuery.where(n);return new Rh(s,this.filterQuery,this.joinCondition)}toSql(){const n=this.filterQuery,s=this.sourceQuery,a=As(n.table.sourceName),c=As(s.table.sourceName);let f=`SELECT ${c}.* FROM ${a} JOIN ${c} ON ${yn(this.joinCondition)}`;const p=[];if(n.whereClause&&p.push(yn(n.whereClause)),s.whereClause&&p.push(yn(s.whereClause)),p.length>0){const v=p.length===1?p[0]:p.map(Ts).join(" AND ");f+=` WHERE ${v}`}return f}},ty=class ta{constructor(n,s){this.table=n,this.whereClause=s}[ma]=!0;where(n){const s=ay(n(this.table.cols)),a=this.whereClause?this.whereClause.and(s):s;return new ta(this.table,a)}rightSemijoin(n,s){const a=new ta(n),c=s(this.table.indexedCols,n.indexedCols);return new Kf(a,this,c)}leftSemijoin(n,s){const a=new ta(n),c=s(this.table.indexedCols,n.indexedCols);return new Kf(this,a,c)}toSql(){return sy(this.table,this.whereClause)}build(){return this}},ry=class{[ma]=!0;type="table";sourceName;accessorName;cols;indexedCols;tableDef;get columns(){return this.tableDef.columns}get indexes(){return this.tableDef.indexes}get rowType(){return this.tableDef.rowType}get constraints(){return this.tableDef.constraints}constructor(r){this.sourceName=r.sourceName,this.accessorName=r.accessorName,this.cols=iy(r),this.indexedCols=this.cols,this.tableDef=r,Object.freeze(this)}asFrom(){return new ty(this)}rightSemijoin(r,n){return this.asFrom().rightSemijoin(r,n)}leftSemijoin(r,n){return this.asFrom().leftSemijoin(r,n)}build(){return this.asFrom().build()}toSql(){return this.asFrom().toSql()}where(r){return this.asFrom().where(r)}};function ny(r){return new ry(r)}function Nh(r){const n=Object.create(null);for(const s of Object.values(r.tables)){const a=ny(s);n[s.accessorName]=a}return Object.freeze(n)}function iy(r){const n={};for(const s of Object.keys(r.columns)){const a=r.columns[s],c=new oy(r.sourceName,s,a.typeBuilder.algebraicType,a.columnMetadata.name);n[s]=Object.freeze(c)}return Object.freeze(n)}function sy(r,n,s=[]){const c=`SELECT * FROM ${As(r.sourceName)}`,f=[];if(n&&f.push(yn(n)),f.push(...s),f.length===0)return c;const p=f.length===1?f[0]:f.map(Ts).join(" AND ");return`${c} WHERE ${p}`}var oy=class{type="column";column;columnName;table;tsValueType;spacetimeType;constructor(r,n,s,a){this.table=r,this.column=n,this.columnName=a||n,this.spacetimeType=s}eq(r){return new rr({type:"eq",left:this,right:Qn(r)})}ne(r){return new rr({type:"ne",left:this,right:Qn(r)})}lt(r){return new rr({type:"lt",left:this,right:Qn(r)})}lte(r){return new rr({type:"lte",left:this,right:Qn(r)})}gt(r){return new rr({type:"gt",left:this,right:Qn(r)})}gte(r){return new rr({type:"gte",left:this,right:Qn(r)})}};function ra(r){return{type:"literal",value:r}}function Qn(r){return r.type==="literal"||typeof r=="object"&&r!=null&&"type"in r&&r.type==="column"?r:ra(r)}function ay(r){return r instanceof rr?r:typeof r=="boolean"?new rr({type:"eq",left:ra(r),right:ra(!0)}):new rr({type:"eq",left:r,right:ra(!0)})}var rr=class na{constructor(n){this.data=n}and(n){return new na({type:"and",clauses:[this.data,n.data]})}or(n){return new na({type:"or",clauses:[this.data,n.data]})}not(){return new na({type:"not",clause:this.data})}};function yn(r,n){const s=r instanceof rr?r.data:r;switch(s.type){case"eq":return`${Mt(s.left)} = ${Mt(s.right)}`;case"ne":return`${Mt(s.left)} <> ${Mt(s.right)}`;case"gt":return`${Mt(s.left)} > ${Mt(s.right)}`;case"gte":return`${Mt(s.left)} >= ${Mt(s.right)}`;case"lt":return`${Mt(s.left)} < ${Mt(s.right)}`;case"lte":return`${Mt(s.left)} <= ${Mt(s.right)}`;case"and":return s.clauses.map(a=>yn(a)).map(Ts).join(" AND ");case"or":return s.clauses.map(a=>yn(a)).map(Ts).join(" OR ");case"not":return`NOT ${Ts(yn(s.clause))}`}}function Ts(r){return`(${r})`}function Mt(r,n){if(uy(r))return ly(r.value);const s=r.table;return`${As(s)}.${As(r.columnName)}`}function ly(r){if(r==null)return"NULL";if(r instanceof Bs||r instanceof ga)return`0x${r.toHexString()}`;if(r instanceof Ci)return`'${r.toISOString()}'`;switch(typeof r){case"number":case"bigint":return String(r);case"boolean":return r?"TRUE":"FALSE";case"string":return`'${r.replace(/'/g,"''")}'`;default:return`'${JSON.stringify(r).replace(/'/g,"''")}'`}}function As(r){return`"${r.replace(/"/g,'""')}"`}function uy(r){return r.type==="literal"}function g(r,n){return{...r,...n}}var Te=class{type;algebraicType;constructor(r){this.algebraicType=r}optional(){return new ca(this)}serialize(r,n){(this.serialize=oe.makeSerializer(this.algebraicType))(r,n)}deserialize(r){return(this.deserialize=oe.makeDeserializer(this.algebraicType))(r)}},cy=class extends Te{constructor(){super(oe.U8)}index(r="btree"){return new Jn(this,g(U,{indexType:r}))}unique(){return new Jn(this,g(U,{isUnique:!0}))}primaryKey(){return new Jn(this,g(U,{isPrimaryKey:!0}))}autoInc(){return new Jn(this,g(U,{isAutoIncrement:!0}))}default(r){return new Jn(this,g(U,{defaultValue:r}))}name(r){return new Jn(this,g(U,{name:r}))}},dy=class extends Te{constructor(){super(oe.U16)}index(r="btree"){return new Gn(this,g(U,{indexType:r}))}unique(){return new Gn(this,g(U,{isUnique:!0}))}primaryKey(){return new Gn(this,g(U,{isPrimaryKey:!0}))}autoInc(){return new Gn(this,g(U,{isAutoIncrement:!0}))}default(r){return new Gn(this,g(U,{defaultValue:r}))}name(r){return new Gn(this,g(U,{name:r}))}},fy=class extends Te{constructor(){super(oe.U32)}index(r="btree"){return new Xn(this,g(U,{indexType:r}))}unique(){return new Xn(this,g(U,{isUnique:!0}))}primaryKey(){return new Xn(this,g(U,{isPrimaryKey:!0}))}autoInc(){return new Xn(this,g(U,{isAutoIncrement:!0}))}default(r){return new Xn(this,g(U,{defaultValue:r}))}name(r){return new Xn(this,g(U,{name:r}))}},hy=class extends Te{constructor(){super(oe.U64)}index(r="btree"){return new Yn(this,g(U,{indexType:r}))}unique(){return new Yn(this,g(U,{isUnique:!0}))}primaryKey(){return new Yn(this,g(U,{isPrimaryKey:!0}))}autoInc(){return new Yn(this,g(U,{isAutoIncrement:!0}))}default(r){return new Yn(this,g(U,{defaultValue:r}))}name(r){return new Yn(this,g(U,{name:r}))}},py=class extends Te{constructor(){super(oe.U128)}index(r="btree"){return new Zn(this,g(U,{indexType:r}))}unique(){return new Zn(this,g(U,{isUnique:!0}))}primaryKey(){return new Zn(this,g(U,{isPrimaryKey:!0}))}autoInc(){return new Zn(this,g(U,{isAutoIncrement:!0}))}default(r){return new Zn(this,g(U,{defaultValue:r}))}name(r){return new Zn(this,g(U,{name:r}))}},gy=class extends Te{constructor(){super(oe.U256)}index(r="btree"){return new ei(this,g(U,{indexType:r}))}unique(){return new ei(this,g(U,{isUnique:!0}))}primaryKey(){return new ei(this,g(U,{isPrimaryKey:!0}))}autoInc(){return new ei(this,g(U,{isAutoIncrement:!0}))}default(r){return new ei(this,g(U,{defaultValue:r}))}name(r){return new ei(this,g(U,{name:r}))}},my=class extends Te{constructor(){super(oe.I8)}index(r="btree"){return new ti(this,g(U,{indexType:r}))}unique(){return new ti(this,g(U,{isUnique:!0}))}primaryKey(){return new ti(this,g(U,{isPrimaryKey:!0}))}autoInc(){return new ti(this,g(U,{isAutoIncrement:!0}))}default(r){return new ti(this,g(U,{defaultValue:r}))}name(r){return new ti(this,g(U,{name:r}))}},yy=class extends Te{constructor(){super(oe.I16)}index(r="btree"){return new ri(this,g(U,{indexType:r}))}unique(){return new ri(this,g(U,{isUnique:!0}))}primaryKey(){return new ri(this,g(U,{isPrimaryKey:!0}))}autoInc(){return new ri(this,g(U,{isAutoIncrement:!0}))}default(r){return new ri(this,g(U,{defaultValue:r}))}name(r){return new ri(this,g(U,{name:r}))}},wy=class extends Te{constructor(){super(oe.I32)}index(r="btree"){return new ni(this,g(U,{indexType:r}))}unique(){return new ni(this,g(U,{isUnique:!0}))}primaryKey(){return new ni(this,g(U,{isPrimaryKey:!0}))}autoInc(){return new ni(this,g(U,{isAutoIncrement:!0}))}default(r){return new ni(this,g(U,{defaultValue:r}))}name(r){return new ni(this,g(U,{name:r}))}},vy=class extends Te{constructor(){super(oe.I64)}index(r="btree"){return new ii(this,g(U,{indexType:r}))}unique(){return new ii(this,g(U,{isUnique:!0}))}primaryKey(){return new ii(this,g(U,{isPrimaryKey:!0}))}autoInc(){return new ii(this,g(U,{isAutoIncrement:!0}))}default(r){return new ii(this,g(U,{defaultValue:r}))}name(r){return new ii(this,g(U,{name:r}))}},_y=class extends Te{constructor(){super(oe.I128)}index(r="btree"){return new si(this,g(U,{indexType:r}))}unique(){return new si(this,g(U,{isUnique:!0}))}primaryKey(){return new si(this,g(U,{isPrimaryKey:!0}))}autoInc(){return new si(this,g(U,{isAutoIncrement:!0}))}default(r){return new si(this,g(U,{defaultValue:r}))}name(r){return new si(this,g(U,{name:r}))}},Sy=class extends Te{constructor(){super(oe.I256)}index(r="btree"){return new oi(this,g(U,{indexType:r}))}unique(){return new oi(this,g(U,{isUnique:!0}))}primaryKey(){return new oi(this,g(U,{isPrimaryKey:!0}))}autoInc(){return new oi(this,g(U,{isAutoIncrement:!0}))}default(r){return new oi(this,g(U,{defaultValue:r}))}name(r){return new oi(this,g(U,{name:r}))}},xy=class extends Te{constructor(){super(oe.F32)}default(r){return new Qf(this,g(U,{defaultValue:r}))}name(r){return new Qf(this,g(U,{name:r}))}},Wf=class extends Te{constructor(){super(oe.F64)}default(r){return new Jf(this,g(U,{defaultValue:r}))}name(r){return new Jf(this,g(U,{name:r}))}},Iy=class extends Te{constructor(){super(oe.Bool)}index(r="btree"){return new _s(this,g(U,{indexType:r}))}unique(){return new _s(this,g(U,{isUnique:!0}))}primaryKey(){return new _s(this,g(U,{isPrimaryKey:!0}))}default(r){return new _s(this,g(U,{defaultValue:r}))}name(r){return new _s(this,g(U,{name:r}))}},ky=class extends Te{constructor(){super(oe.String)}index(r="btree"){return new Ss(this,g(U,{indexType:r}))}unique(){return new Ss(this,g(U,{isUnique:!0}))}primaryKey(){return new Ss(this,g(U,{isPrimaryKey:!0}))}default(r){return new Ss(this,g(U,{defaultValue:r}))}name(r){return new Ss(this,g(U,{name:r}))}},hu=class extends Te{element;constructor(r){super(oe.Array(r.algebraicType)),this.element=r}default(r){return new Gf(this,g(U,{defaultValue:r}))}name(r){return new Gf(this,g(U,{name:r}))}},by=class extends Te{constructor(){super(oe.Array(oe.U8))}default(r){return new Xf(g(U,{defaultValue:r}))}name(r){return new Xf(g(U,{name:r}))}},ca=class extends Te{value;constructor(r){super(Xm.getAlgebraicType(r.algebraicType)),this.value=r}default(r){return new Yf(this,g(U,{defaultValue:r}))}name(r){return new Yf(this,g(U,{name:r}))}},ki=class extends Te{typeName;elements;constructor(r,n){function s(a){return Object.keys(a).map(c=>({name:c,get algebraicType(){return a[c].algebraicType}}))}super(oe.Product({elements:s(r)})),this.typeName=n,this.elements=r}default(r){return new Zf(this,g(U,{defaultValue:r}))}name(r){return new Zf(this,g(U,{name:r}))}},pu=class extends Te{ok;err;constructor(r,n){super(Ym.getAlgebraicType(r.algebraicType,n.algebraicType)),this.ok=r,this.err=n}default(r){return new By(this,g(U,{defaultValue:r}))}},ju=class extends Te{constructor(){super({tag:"Product",value:{elements:[]}})}},wn=class extends Te{row;typeName;constructor(r,n){const s=Object.fromEntries(Object.entries(r).map(([c,f])=>[c,f instanceof Ee?f:new Ee(f,{})])),a=Object.keys(s).map(c=>({name:c,get algebraicType(){return s[c].typeBuilder.algebraicType}}));super(oe.Product({elements:a})),this.row=s,this.typeName=n}},Ph=class extends Te{variants;typeName;constructor(r,n){function s(a){return Object.keys(a).map(c=>({name:c,get algebraicType(){return a[c].algebraicType}}))}super(oe.Sum({variants:s(r)})),this.variants=r,this.typeName=n;for(const a of Object.keys(r)){const c=Object.getOwnPropertyDescriptor(r,a),f=!!c&&(typeof c.get=="function"||typeof c.set=="function");let p=!1;if(f||(p=r[a]instanceof ju),p){const v=this.create(a);Object.defineProperty(this,a,{value:v,writable:!1,enumerable:!0,configurable:!1})}else Object.defineProperty(this,a,{value:(y=>this.create(a,y)),writable:!1,enumerable:!0,configurable:!1})}}create(r,n){return n===void 0?{tag:r}:{tag:r,value:n}}default(r){return new xu(this,g(U,{defaultValue:r}))}name(r){return new xu(this,g(U,{name:r}))}},gu=Ph,Cy=class extends Ph{index(r="btree"){return new eh(this,g(U,{indexType:r}))}primaryKey(){return new eh(this,g(U,{isPrimaryKey:!0}))}},Ty=class extends Te{constructor(){super(Uh.getAlgebraicType())}default(r){return new th(this,g(U,{defaultValue:r}))}name(r){return new th(this,g(U,{name:r}))}},Ey=class extends Te{constructor(){super(Bs.getAlgebraicType())}index(r="btree"){return new ai(this,g(U,{indexType:r}))}unique(){return new ai(this,g(U,{isUnique:!0}))}primaryKey(){return new ai(this,g(U,{isPrimaryKey:!0}))}autoInc(){return new ai(this,g(U,{isAutoIncrement:!0}))}default(r){return new ai(this,g(U,{defaultValue:r}))}name(r){return new ai(this,g(U,{name:r}))}},Uy=class extends Te{constructor(){super(ga.getAlgebraicType())}index(r="btree"){return new li(this,g(U,{indexType:r}))}unique(){return new li(this,g(U,{isUnique:!0}))}primaryKey(){return new li(this,g(U,{isPrimaryKey:!0}))}autoInc(){return new li(this,g(U,{isAutoIncrement:!0}))}default(r){return new li(this,g(U,{defaultValue:r}))}name(r){return new li(this,g(U,{name:r}))}},Ry=class extends Te{constructor(){super(Ci.getAlgebraicType())}index(r="btree"){return new ui(this,g(U,{indexType:r}))}unique(){return new ui(this,g(U,{isUnique:!0}))}primaryKey(){return new ui(this,g(U,{isPrimaryKey:!0}))}autoInc(){return new ui(this,g(U,{isAutoIncrement:!0}))}default(r){return new ui(this,g(U,{defaultValue:r}))}name(r){return new ui(this,g(U,{name:r}))}},Ny=class extends Te{constructor(){super(bi.getAlgebraicType())}index(r="btree"){return new ci(this,g(U,{indexType:r}))}unique(){return new ci(this,g(U,{isUnique:!0}))}primaryKey(){return new ci(this,g(U,{isPrimaryKey:!0}))}autoInc(){return new ci(this,g(U,{isAutoIncrement:!0}))}default(r){return new ci(this,g(U,{defaultValue:r}))}name(r){return new ci(this,g(U,{name:r}))}},Py=class extends Te{constructor(){super(vh.getAlgebraicType())}index(r="btree"){return new di(this,g(U,{indexType:r}))}unique(){return new di(this,g(U,{isUnique:!0}))}primaryKey(){return new di(this,g(U,{isPrimaryKey:!0}))}autoInc(){return new di(this,g(U,{isAutoIncrement:!0}))}default(r){return new di(this,g(U,{defaultValue:r}))}name(r){return new di(this,g(U,{name:r}))}},U={},Ee=class{typeBuilder;columnMetadata;constructor(r,n){this.typeBuilder=r,this.columnMetadata=n}serialize(r,n){this.typeBuilder.serialize(r,n)}deserialize(r){return this.typeBuilder.deserialize(r)}},Jn=class nn extends Ee{index(n="btree"){return new nn(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new nn(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new nn(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}autoInc(){return new nn(this.typeBuilder,g(this.columnMetadata,{isAutoIncrement:!0}))}default(n){return new nn(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new nn(this.typeBuilder,g(this.columnMetadata,{name:n}))}},Gn=class sn extends Ee{index(n="btree"){return new sn(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new sn(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new sn(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}autoInc(){return new sn(this.typeBuilder,g(this.columnMetadata,{isAutoIncrement:!0}))}default(n){return new sn(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new sn(this.typeBuilder,g(this.columnMetadata,{name:n}))}},Xn=class on extends Ee{index(n="btree"){return new on(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new on(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new on(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}autoInc(){return new on(this.typeBuilder,g(this.columnMetadata,{isAutoIncrement:!0}))}default(n){return new on(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new on(this.typeBuilder,g(this.columnMetadata,{name:n}))}},Yn=class an extends Ee{index(n="btree"){return new an(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new an(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new an(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}autoInc(){return new an(this.typeBuilder,g(this.columnMetadata,{isAutoIncrement:!0}))}default(n){return new an(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new an(this.typeBuilder,g(this.columnMetadata,{name:n}))}},Zn=class ln extends Ee{index(n="btree"){return new ln(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new ln(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new ln(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}autoInc(){return new ln(this.typeBuilder,g(this.columnMetadata,{isAutoIncrement:!0}))}default(n){return new ln(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new ln(this.typeBuilder,g(this.columnMetadata,{name:n}))}},ei=class un extends Ee{index(n="btree"){return new un(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new un(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new un(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}autoInc(){return new un(this.typeBuilder,g(this.columnMetadata,{isAutoIncrement:!0}))}default(n){return new un(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new un(this.typeBuilder,g(this.columnMetadata,{name:n}))}},ti=class cn extends Ee{index(n="btree"){return new cn(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new cn(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new cn(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}autoInc(){return new cn(this.typeBuilder,g(this.columnMetadata,{isAutoIncrement:!0}))}default(n){return new cn(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new cn(this.typeBuilder,g(this.columnMetadata,{name:n}))}},ri=class dn extends Ee{index(n="btree"){return new dn(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new dn(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new dn(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}autoInc(){return new dn(this.typeBuilder,g(this.columnMetadata,{isAutoIncrement:!0}))}default(n){return new dn(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new dn(this.typeBuilder,g(this.columnMetadata,{name:n}))}},ni=class fn extends Ee{index(n="btree"){return new fn(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new fn(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new fn(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}autoInc(){return new fn(this.typeBuilder,g(this.columnMetadata,{isAutoIncrement:!0}))}default(n){return new fn(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new fn(this.typeBuilder,g(this.columnMetadata,{name:n}))}},ii=class hn extends Ee{index(n="btree"){return new hn(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new hn(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new hn(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}autoInc(){return new hn(this.typeBuilder,g(this.columnMetadata,{isAutoIncrement:!0}))}default(n){return new hn(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new hn(this.typeBuilder,g(this.columnMetadata,{name:n}))}},si=class pn extends Ee{index(n="btree"){return new pn(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new pn(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new pn(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}autoInc(){return new pn(this.typeBuilder,g(this.columnMetadata,{isAutoIncrement:!0}))}default(n){return new pn(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new pn(this.typeBuilder,g(this.columnMetadata,{name:n}))}},oi=class gn extends Ee{index(n="btree"){return new gn(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new gn(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new gn(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}autoInc(){return new gn(this.typeBuilder,g(this.columnMetadata,{isAutoIncrement:!0}))}default(n){return new gn(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new gn(this.typeBuilder,g(this.columnMetadata,{name:n}))}},Qf=class mu extends Ee{default(n){return new mu(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new mu(this.typeBuilder,g(this.columnMetadata,{name:n}))}},Jf=class yu extends Ee{default(n){return new yu(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new yu(this.typeBuilder,g(this.columnMetadata,{name:n}))}},_s=class gi extends Ee{index(n="btree"){return new gi(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new gi(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new gi(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}default(n){return new gi(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new gi(this.typeBuilder,g(this.columnMetadata,{name:n}))}},Ss=class mi extends Ee{index(n="btree"){return new mi(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new mi(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new mi(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}default(n){return new mi(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new mi(this.typeBuilder,g(this.columnMetadata,{name:n}))}},Gf=class wu extends Ee{default(n){return new wu(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new wu(this.typeBuilder,g(this.columnMetadata,{name:n}))}},Xf=class vu extends Ee{constructor(n){super(new Te(oe.Array(oe.U8)),n)}default(n){return new vu(g(this.columnMetadata,{defaultValue:n}))}name(n){return new vu(g(this.columnMetadata,{name:n}))}},Yf=class _u extends Ee{default(n){return new _u(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new _u(this.typeBuilder,g(this.columnMetadata,{name:n}))}},By=class Bh extends Ee{constructor(n,s){super(n,s)}default(n){return new Bh(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}},Zf=class Su extends Ee{default(n){return new Su(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new Su(this.typeBuilder,g(this.columnMetadata,{name:n}))}},xu=class Iu extends Ee{default(n){return new Iu(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new Iu(this.typeBuilder,g(this.columnMetadata,{name:n}))}},eh=class ku extends xu{index(n="btree"){return new ku(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}primaryKey(){return new ku(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}},th=class bu extends Ee{default(n){return new bu(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new bu(this.typeBuilder,g(this.columnMetadata,{name:n}))}},ai=class yi extends Ee{index(n="btree"){return new yi(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new yi(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new yi(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}default(n){return new yi(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new yi(this.typeBuilder,g(this.columnMetadata,{name:n}))}},li=class wi extends Ee{index(n="btree"){return new wi(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new wi(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new wi(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}default(n){return new wi(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new wi(this.typeBuilder,g(this.columnMetadata,{name:n}))}},ui=class vi extends Ee{index(n="btree"){return new vi(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new vi(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new vi(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}default(n){return new vi(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new vi(this.typeBuilder,g(this.columnMetadata,{name:n}))}},ci=class _i extends Ee{index(n="btree"){return new _i(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new _i(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new _i(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}default(n){return new _i(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new _i(this.typeBuilder,g(this.columnMetadata,{name:n}))}},di=class Si extends Ee{index(n="btree"){return new Si(this.typeBuilder,g(this.columnMetadata,{indexType:n}))}unique(){return new Si(this.typeBuilder,g(this.columnMetadata,{isUnique:!0}))}primaryKey(){return new Si(this.typeBuilder,g(this.columnMetadata,{isPrimaryKey:!0}))}default(n){return new Si(this.typeBuilder,g(this.columnMetadata,{defaultValue:n}))}name(n){return new Si(this.typeBuilder,g(this.columnMetadata,{name:n}))}},Ay=class extends Te{ref;__spacetimeType;constructor(r){super(oe.Ref(r)),this.ref=r}},My=((r,n)=>{let s=r,a;if(typeof r=="string"){if(!n)throw new TypeError("When providing a name, you must also provide the variants object or array.");s=n,a=r}if(Array.isArray(s)){const c={};for(const f of s)c[f]=new ju;return new Cy(c,a)}return new gu(s,a)}),d={bool:()=>new Iy,string:()=>new ky,number:()=>new Wf,i8:()=>new my,u8:()=>new cy,i16:()=>new yy,u16:()=>new dy,i32:()=>new wy,u32:()=>new fy,i64:()=>new vy,u64:()=>new hy,i128:()=>new _y,u128:()=>new py,i256:()=>new Sy,u256:()=>new gy,f32:()=>new xy,f64:()=>new Wf,object:((r,n)=>{if(typeof r=="string"){if(!n)throw new TypeError("When providing a name, you must also provide the object.");return new ki(n,r)}return new ki(r,void 0)}),row:((r,n)=>{const[s,a]=typeof r=="string"?[n,r]:[r,void 0];return new wn(s,a)}),array(r){return new hu(r)},enum:My,unit(){return new ju},lazy(r){let n=null;const s=()=>n??=r();return new Proxy({},{get(c,f,p){const v=s(),y=Reflect.get(v,f,p);return typeof y=="function"?y.bind(v):y},set(c,f,p,v){return Reflect.set(s(),f,p,v)},has(c,f){return f in s()},ownKeys(){return Reflect.ownKeys(s())},getOwnPropertyDescriptor(c,f){return Object.getOwnPropertyDescriptor(s(),f)},getPrototypeOf(){return Object.getPrototypeOf(s())}})},scheduleAt:()=>new Ty,option(r){return new ca(r)},result(r,n){return new pu(r,n)},identity:()=>new Ey,connectionId:()=>new Uy,timestamp:()=>new Ry,timeDuration:()=>new Ny,uuid:()=>new Py,byteArray:()=>new by},da=d.object("BsatnRowList",{get sizeHint(){return Jy},rowsData:d.byteArray()}),jy=d.object("CallProcedure",{requestId:d.u32(),flags:d.u8(),procedure:d.string(),args:d.byteArray()}),Oy=d.object("CallReducer",{requestId:d.u32(),flags:d.u8(),reducer:d.string(),args:d.byteArray()}),xs=d.enum("ClientMessage",{get Subscribe(){return Yy},get Unsubscribe(){return nw},get OneOffQuery(){return Fy},get CallReducer(){return Oy},get CallProcedure(){return jy}}),Dy=d.object("EventTableRows",{get events(){return da}}),zy=d.object("InitialConnection",{identity:d.identity(),connectionId:d.connectionId(),token:d.string()}),Fy=d.object("OneOffQuery",{requestId:d.u32(),queryString:d.string()}),$y=d.object("OneOffQueryResult",{requestId:d.u32(),get result(){return d.result(Ou,d.string())}}),Ly=d.object("PersistentTableRows",{get inserts(){return da},get deletes(){return da}}),Vy=d.object("ProcedureResult",{get status(){return qy},timestamp:d.timestamp(),totalHostExecutionDuration:d.timeDuration(),requestId:d.u32()}),qy=d.enum("ProcedureStatus",{Returned:d.byteArray(),InternalError:d.string()}),Ou=d.object("QueryRows",{get tables(){return d.array(Xy)}}),Ei=d.object("QuerySetId",{id:d.u32()}),Hy=d.object("QuerySetUpdate",{get querySetId(){return Ei},get tables(){return d.array(tw)}}),Ky=d.object("ReducerOk",{retValue:d.byteArray(),get transactionUpdate(){return Ah}}),Wy=d.enum("ReducerOutcome",{get Ok(){return Ky},OkEmpty:d.unit(),Err:d.byteArray(),InternalError:d.string()}),Qy=d.object("ReducerResult",{requestId:d.u32(),timestamp:d.timestamp(),get result(){return Wy}}),Jy=d.enum("RowSizeHint",{FixedSize:d.u16(),RowOffsets:d.array(d.u64())}),Gy=d.enum("ServerMessage",{get InitialConnection(){return zy},get SubscribeApplied(){return Zy},get UnsubscribeApplied(){return iw},get SubscriptionError(){return ew},get TransactionUpdate(){return Ah},get OneOffQueryResult(){return $y},get ReducerResult(){return Qy},get ProcedureResult(){return Vy}}),Xy=d.object("SingleTableRows",{table:d.string(),get rows(){return da}}),Yy=d.object("Subscribe",{requestId:d.u32(),get querySetId(){return Ei},queryStrings:d.array(d.string())}),Zy=d.object("SubscribeApplied",{requestId:d.u32(),get querySetId(){return Ei},get rows(){return Ou}}),ew=d.object("SubscriptionError",{requestId:d.option(d.u32()),get querySetId(){return Ei},error:d.string()}),tw=d.object("TableUpdate",{tableName:d.string(),get rows(){return d.array(rw)}}),rw=d.enum("TableUpdateRows",{get PersistentTable(){return Ly},get EventTable(){return Dy}}),Ah=d.object("TransactionUpdate",{get querySets(){return d.array(Hy)}}),nw=d.object("Unsubscribe",{requestId:d.u32(),get querySetId(){return Ei},get flags(){return Mh}}),iw=d.object("UnsubscribeApplied",{requestId:d.u32(),get querySetId(){return Ei},get rows(){return d.option(Ou)}}),Mh=d.enum("UnsubscribeFlags",{Default:d.unit(),SendDroppedRows:d.unit()}),Du=class{#e=new Map;on(r,n){let s=this.#e.get(r);s||(s=new Set,this.#e.set(r,s)),s.add(n)}off(r,n){const s=this.#e.get(r);s&&s.delete(n)}emit(r,...n){const s=this.#e.get(r);if(s)for(const a of s)a(...n)}},sw={component:"📦",info:"ℹ️",warn:"⚠️",error:"❌",debug:"🐛",trace:"🔍"},ow={component:"color: #fff; background-color: #8D6FDD; padding: 2px 5px; border-radius: 3px;",info:"color: #fff; background-color: #007bff; padding: 2px 5px; border-radius: 3px;",warn:"color: #fff; background-color: #ffc107; padding: 2px 5px; border-radius: 3px;",error:"color: #fff; background-color: #dc3545; padding: 2px 5px; border-radius: 3px;",debug:"color: #fff; background-color: #28a745; padding: 2px 5px; border-radius: 3px;",trace:"color: #fff; background-color: #17a2b8; padding: 2px 5px; border-radius: 3px;"},aw={component:"color: #8D6FDD;",info:"color: #007bff;",warn:"color: #ffc107;",error:"color: #dc3545;",debug:"color: #28a745;",trace:"color: #17a2b8;"},rh={error:0,warn:1,info:2,debug:3,trace:4},lw="info",uw=r=>rh[r]<=rh[lw],nh=r=>typeof r=="function"?r():r,ih=r=>Array.from(r).map(n=>n.toString(16).padStart(2,"0")).join(""),cw=25,dw=10,fw=new Set(["token","authToken","authorization","accessToken","refreshToken"]),au=r=>Lf(r,(n,s)=>{if(fw.has(n))return"[REDACTED]";if(s&&typeof s=="object"&&"__identity__"in s&&typeof s.__identity__=="bigint")return bh(s.__identity__);if(s&&typeof s=="object"&&"__connection_id__"in s&&typeof s.__connection_id__=="bigint")return Ih(s.__connection_id__);if(s instanceof Uint8Array){if(s.length<25)return`0x${ih(s)}`;const a=s.subarray(0,10);return`Uint8Array(len=${s.length}, head=0x${ih(a)})`}if(Array.isArray(s)&&s.length>=cw){const a=Lf(s.slice(0,dw));return`Array(len=${s.length}, head=${a??"[]"})`}return s}),et=(r,n,...s)=>{if(!uw(r))return;const a=nh(n),c=s.map(nh);console.log(`%c${sw[r]} ${r.toUpperCase()}%c ${a}`,ow[r],aw[r],...c)},sh=(r,n)=>r===n?0:rs.map(y=>v[y]),c=(v,y)=>{const x=a(v),R=Array.isArray(y)?y:[y],N=Math.max(0,R.length-1);for(let q=0;q0||$===0&&Q.tag==="excluded")return!1}return!0}else return!!Is(O,j)},f=r.constraints.some(v=>v.constraint!=="unique"?!1:Is(v.columns,n.columns)),p=this;return f?{find:y=>{const x=Array.isArray(y)?y:[y];for(const R of p.iter())if(Is(a(R),x))return R;return null}}:{*filter(y){for(const x of p.iter())c(x,y)&&(yield x)}}}count(){return BigInt(this.rows.size)}iter(){function*r(n){for(const[s]of n.values())yield s}return r(this.rows)}[Symbol.iterator](){return this.iter()}applyOperations=(r,n)=>{const s=[];if(this.tableDef.isEvent){for(const c of r)c.type==="insert"&&s.push({type:"insert",table:this.tableDef.sourceName,cb:()=>{this.emitter.emit("insert",n,c.row)}});return s}if(Object.values(this.tableDef.columns).some(c=>c.columnMetadata.isPrimaryKey===!0)){const c=new Map,f=new Map;for(const p of r)if(p.type==="insert"){const[v,y]=c.get(p.rowId)||[p,0];c.set(p.rowId,[p,y+1])}else{const[v,y]=f.get(p.rowId)||[p,0];f.set(p.rowId,[p,y+1])}for(const[p,[v,y]]of c){const x=f.get(p);if(x){const[R,N]=x,j=y-N,O=this.update(n,p,v.row,j);O&&s.push(O),f.delete(p)}else{const R=this.insert(n,v,y);R&&s.push(R)}}for(const[p,v]of f.values()){const y=this.delete(n,p,v);y&&s.push(y)}}else for(const c of r)if(c.type==="insert"){const f=this.insert(n,c);f&&s.push(f)}else{const f=this.delete(n,c);f&&s.push(f)}return s};update=(r,n,s,a=0)=>{const c=this.rows.get(n);if(!c){et("error",`Updating a row that was not present in the cache. Table: ${this.tableDef.sourceName}, RowId: ${n}`);return}const[f,p]=c,v=Math.max(1,p+a);if(p+a<=0){et("error",`Negative reference count for in table ${this.tableDef.sourceName} row ${n} (${p} + ${a})`);return}return this.rows.set(n,[s,v]),p===0?(et("error",`Updating a row id in table ${this.tableDef.sourceName} which was not present in the cache (rowId: ${n})`),{type:"insert",table:this.tableDef.sourceName,cb:()=>{this.emitter.emit("insert",r,s)}}):{type:"update",table:this.tableDef.sourceName,cb:()=>{this.emitter.emit("update",r,f,s)}}};insert=(r,n,s=1)=>{const[a,c]=this.rows.get(n.rowId)||[n.row,0];if(this.rows.set(n.rowId,[n.row,c+s]),c===0)return{type:"insert",table:this.tableDef.sourceName,cb:()=>{this.emitter.emit("insert",r,n.row)}}};delete=(r,n,s=1)=>{const[a,c]=this.rows.get(n.rowId)||[n.row,0];if(c===0){et("warn","Deleting a row that was not present in the cache");return}if(c<=s)return this.rows.delete(n.rowId),{type:"delete",table:this.tableDef.sourceName,cb:()=>{this.emitter.emit("delete",r,n.row)}};this.rows.set(n.rowId,[n.row,c-s])};onInsert=r=>{this.emitter.on("insert",r)};onDelete=r=>{this.emitter.on("delete",r)};onUpdate=r=>{this.emitter.on("update",r)};removeOnInsert=r=>{this.emitter.off("insert",r)};removeOnDelete=r=>{this.emitter.off("delete",r)};removeOnUpdate=r=>{this.emitter.off("update",r)}},pw=class{map=new Map;get(r){return this.map.get(r)}set(r,n){return this.map.set(r,n),this}has(r){return this.map.has(r)}delete(r){return this.map.delete(r)}keys(){return this.map.keys()}values(){return this.map.values()}entries(){return this.map.entries()}[Symbol.iterator](){return this.entries()}},gw=class{tables=new pw;getTable(r){const n=this.tables.get(r);if(!n)throw console.error("The table has not been registered for this client. Please register the table before using it. If you have registered global tables using the SpacetimeDBClient.registerTables() or `registerTable()` method, please make sure that is executed first!"),new Error(`Table ${String(r)} does not exist`);return n}getOrCreateTable(r){const n=r.accessorName,s=this.tables.get(n);if(s)return s;const a=new hw(r);return this.tables.set(n,a),a}};function mw(r,n){const s=Math.min(r.length,n.length);for(let a=0;aisNaN(Number(x))?x:Number(x)):null,y=a[5]||null;return new Cu(c,f,p,v,y)}},Oh=new jh(1,4,0);function yw(r){if(r===void 0)throw new Error(oh(r));if(jh.parseVersionString(r).compare(Oh)<0)throw new Error(oh(r))}function oh(r){return`Module code was generated with an incompatible version of the spacetimedb cli (${r}). Update the cli version to at least ${Oh.toString()} and regenerate the bindings. You can upgrade to the latest cli version by running: spacetime version upgrade`}async function ww(r,n,s=128*1024){let a=0;const c=new ReadableStream({pull(O){if(a{const a=await this.#t(new Uint8Array(s.data));n({data:a})}}set onerror(n){this.#e.onerror=n}#e;async#t(n){const s=n[0],a=n.subarray(1);switch(s){case 0:return a;case 1:throw new Error("Brotli Compression not supported. Please use gzip or none compression in withCompression method on DbConnection.");case 2:return await ww(a,"gzip");default:throw new Error("Unexpected Compression Algorithm. Please use `gzip` or `none`")}}send(n){this.#e.send(n)}close(){this.#e.close()}constructor(n){n.binaryType="arraybuffer",this.#e=n}static async createWebSocketFn({url:n,nameOrAddress:s,wsProtocol:a,authToken:c,compression:f,lightMode:p,confirmedReads:v}){const y=new Headers,x=await vw();let R;if(c){y.set("Authorization",`Bearer ${c}`);const O=new URL("v1/identity/websocket-token",n);O.protocol=n.protocol==="wss:"?"https:":"http:";const q=await fetch(O,{method:"POST",headers:y});if(q.ok){const{token:Q}=await q.json();R=Q}else return Promise.reject(new Error(`Failed to verify token: ${q.statusText}`))}const N=new URL(`v1/database/${s}/subscribe`,n);R&&N.searchParams.set("token",R),N.searchParams.set("compression",f==="gzip"?"Gzip":"None"),p&&N.searchParams.set("light","true"),v!==void 0&&N.searchParams.set("confirmed",v.toString());const j=new x(N.toString(),a);return new Dh(j)}},Sw=class{constructor(n,s){this.remoteModule=n,this.dbConnectionCtor=s,this.#o=_w.createWebSocketFn}#e;#t;#n;#r;#i=new Du;#a="gzip";#s=!1;#l;#o;withUri(n){return this.#e=new URL(n),this}withDatabaseName(n){return this.#t=n,this}withToken(n){return this.#r=n,this}withWSFn(n){return this.#o=n,this}withCompression(n){return this.#a=n,this}withLightMode(n){return this.#s=n,this}withConfirmedReads(n){return this.#l=n,this}onConnect(n){return this.#i.on("connect",n),this}onConnectError(n){return this.#i.on("connectError",n),this}onDisconnect(n){return this.#i.on("disconnect",n),this}getUri(){return this.#e?.toString()??""}getModuleName(){return this.#t??""}build(){if(!this.#e)throw new Error("URI is required to connect to SpacetimeDB");if(!this.#t)throw new Error("Database name or address is required to connect to SpacetimeDB");return yw(this.remoteModule.versionInfo?.cliVersion),this.dbConnectionCtor({uri:this.#e,nameOrAddress:this.#t,identity:this.#n,token:this.#r,emitter:this.#i,compression:this.#a,lightMode:this.#s,confirmedReads:this.#l,createWSFn:this.#o,remoteModule:this.remoteModule})}},zh=Symbol("INTERNAL_REMOTE_MODULE"),Fh=class{constructor(r){this.db=r}#e=void 0;#t=void 0;onApplied(r){return this.#e=r,this}onError(r){return this.#t=r,this}subscribe(r){let n;if(typeof r=="function"){const a=this.db.getTablesMap?.(),c=r(a);n=Array.isArray(c)?c:[c]}else n=Array.isArray(r)?r:[r];if(n.length===0)throw new Error("Subscriptions must have at least one query");const s=n.map(a=>{if(typeof a=="string")return a;if(Zm(a))return ey(a);throw new Error("Subscriptions must be SQL strings or typed queries")});return new Iw(this.db,s,this.#e,this.#t)}subscribeToAllTables(){const r=this.db[zh](),n=Object.values(r.tables).map(s=>`SELECT * FROM ${s.sourceName}`);this.subscribe(n)}},xw=class{subscriptions=new Map},Iw=class{constructor(r,n,s,a){this.db=r,this.#i.on("applied",c=>{this.#r=!0,s&&s(c)}),this.#i.on("error",(c,f)=>{this.#r=!1,this.#n=!0,a&&a(c,f)}),this.#e=this.db.registerSubscription(this,this.#i,n)}#e;#t=!1;#n=!1;#r=!1;#i=new Du;unsubscribe(){if(this.#t)throw new Error("Unsubscribe has already been called");this.#t=!0,this.db.unregisterSubscription(this.#e),this.#i.on("end",r=>{this.#n=!0,this.#r=!1})}unsubscribeThen(r){if(this.#n)throw new Error("Subscription has already ended");if(this.#t)throw new Error("Unsubscribe has already been called");this.#t=!0,this.db.unregisterSubscription(this.#e),this.#i.on("end",n=>{this.#n=!0,this.#r=!1,r(n)})}isEnded(){return this.#n}isActive(){return this.#r}},kw=class{isActive=!1;identity=void 0;token=void 0;[zh](){return this.#l}db;reducers;procedures;connectionId=ga.random();#e=0;#t=0;#n=0;#r;#i=Promise.resolve();#a=[];#s=new xw;#l;#o=new Map;#y=new Map;#w=new Map;#v;#f;#h;#u;clientCache;ws;wsPromise;constructor({uri:r,nameOrAddress:n,identity:s,token:a,emitter:c,remoteModule:f,createWSFn:p,compression:v,lightMode:y,confirmedReads:x}){et("info","Connecting to SpacetimeDB WS...");const R=new URL(r.toString());/^wss?:/.test(r.protocol)||(R.protocol=R.protocol==="https:"?"wss:":"ws:"),this.identity=s,this.token=a,this.#l=f,this.#r=c,this.#v=Object.create(null),this.#u=Object.create(null);for(const j of Object.values(f.tables))this.#v[j.sourceName]=pr.makeDeserializer(j.rowType),this.#u[j.sourceName]=j;this.#f=Object.create(null);for(const j of f.reducers)this.#f[j.name]={serialize:pr.makeSerializer(j.paramsType),deserialize:pr.makeDeserializer(j.paramsType)};this.#h=Object.create(null);for(const j of f.procedures)this.#h[j.name]={serializeArgs:pr.makeSerializer(new ki(j.params).algebraicType.value),deserializeReturn:oe.makeDeserializer(j.returnType.algebraicType)};const N=this.connectionId.toHexString();R.searchParams.set("connection_id",N),this.clientCache=new gw,this.db=this.#C(),this.reducers=this.#T(f),this.procedures=this.#E(f),this.wsPromise=p({url:R,nameOrAddress:n,wsProtocol:"v2.bsatn.spacetimedb",authToken:a,compression:v,lightMode:y,confirmedReads:x}).then(j=>(this.ws=j,this.ws.onclose=()=>{this.#r.emit("disconnect",this),this.isActive=!1},this.ws.onerror=O=>{this.#r.emit("connectError",this,O),this.isActive=!1},this.ws.onopen=this.#P.bind(this),this.ws.onmessage=this.#A.bind(this),j)).catch(j=>{et("error","Error connecting to SpacetimeDB WS"),this.#r.emit("connectError",this,j)})}#b=()=>{const r=this.#e;return this.#e+=1,r};#p=()=>this.#t++;#C(){const r=Object.create(null);for(const n of Object.values(this.#u)){const s=n.accessorName;Object.defineProperty(r,s,{enumerable:!0,configurable:!1,get:()=>this.clientCache.getOrCreateTable(n)})}return r}#T(r){const n={},s=new Pe(1024);for(const a of r.reducers){const c=a.name,f=a.accessorName,{serialize:p}=this.#f[c];n[f]=v=>{s.clear(),p(s,v);const y=s.getBuffer();return this.callReducer(c,y,v)}}return n}#E(r){const n={},s=new Pe(1024);for(const a of r.procedures){const c=a.name,f=a.accessorName,{serializeArgs:p,deserializeReturn:v}=this.#h[c];n[f]=y=>{s.clear(),p(s,y);const x=s.getBuffer();return this.callProcedure(c,x).then(R=>v(new ze(R)))}}return n}#c(r){return{db:this.db,reducers:this.reducers,isActive:this.isActive,subscriptionBuilder:this.subscriptionBuilder.bind(this),disconnect:this.disconnect.bind(this),event:r}}subscriptionBuilder=()=>new Fh(this);getTablesMap(){return Nh({tables:this.#l.tables})}registerSubscription(r,n,s){const a=this.#b();this.#s.subscriptions.set(a,{handle:r,emitter:n});const c=this.#p();return this.#m(xs.Subscribe({queryStrings:s,querySetId:{id:a},requestId:c})),a}unregisterSubscription(r){const n=this.#p();this.#m(xs.Unsubscribe({querySetId:{id:r},requestId:n,flags:Mh.SendDroppedRows}))}#g(r,n,s){const a=s.rowsData,c=new ze(a),f=[],p=this.#v[n],v=this.#u[n],x=Object.entries(v.columns).find(N=>N[1].columnMetadata.isPrimaryKey);let R=0;for(;c.remaining>0;){const N=p(c);let j;if(x!==void 0){const O=x[0],q=x[1].typeBuilder.algebraicType;j=oe.intoMapKey(q,N[O])}else{const O=a.subarray(R,c.offset);j=Mu.fromByteArray(O)}R=c.offset,f.push({type:r,rowId:j,row:N})}return f}#_(r){const n=new Map;for(const s of r){const a=n.get(s.tableName);if(a)for(const c of s.operations)a.push(c);else n.set(s.tableName,s.operations.slice())}return Array.from(n,([s,a])=>({tableName:s,operations:a}))}#x(r,n){const s=[];for(const a of r.tables)s.push({tableName:a.table,operations:this.#g(n,a.table,a.rows)});return this.#_(s)}#U(r,n){if(n.tag==="PersistentTable"){const s=this.#g("insert",r,n.value.inserts),a=this.#g("delete",r,n.value.deletes);return s.concat(a)}return n.tag==="EventTable"?this.#g("insert",r,n.value.events):[]}#R(r){const n=[];for(const s of r.tables){let a=[];for(const c of s.rows)a=a.concat(this.#U(s.tableName,c));n.push({tableName:s.tableName,operations:a})}return this.#_(n)}#I(r){const n=this.#a.splice(0);for(const s of n)r.send(s)}#N=new Pe(1024);#m(r){const n=this.#N;n.clear(),xs.serialize(n,r);const s=n.getBuffer();this.ws&&this.isActive?(this.#a.length&&this.#I(this.ws),et("trace",()=>`Sending message to server: ${au(r)}`),this.ws.send(s)):(et("trace",()=>`Queuing message to server: ${au(r)}`),this.#a.push(s.slice()))}#d(){return this.#n+=1,`${this.connectionId.toHexString()}:${this.#n}`}#P(){this.isActive=!0,this.ws&&this.#I(this.ws)}#S(r,n){const s=[];for(const a of r){const c=a.tableName,f=this.#u[c],v=this.clientCache.getOrCreateTable(f).applyOperations(a.operations,n);for(const y of v)s.push(y)}return s}#k(r,n){const s=[];for(const a of n.querySets){const c=this.#R(a);for(const f of c)s.push(f)}return this.#S(this.#_(s),r)}async#B(r){const n=Gy.deserialize(new ze(r));switch(et("trace",()=>`Processing server message: ${au(n)}`),n.tag){case"InitialConnection":{this.identity=n.value.identity,!this.token&&n.value.token&&(this.token=n.value.token),this.connectionId=n.value.connectionId,this.#r.emit("connect",this,this.identity,this.token);break}case"SubscribeApplied":{const s=n.value.querySetId.id,a=this.#s.subscriptions.get(s);if(!a){et("error",`Received SubscribeApplied for unknown querySetId ${s}.`);return}const c={id:this.#d(),tag:"SubscribeApplied"},f=this.#c(c),p=this.#x(n.value.rows,"insert"),v=this.#S(p,f),{event:y,...x}=f;a.emitter.emit("applied",x),et("trace",()=>`Calling ${v.length} triggered row callbacks`);for(const R of v)R.cb();break}case"UnsubscribeApplied":{const s=n.value.querySetId.id,a=this.#s.subscriptions.get(s);if(!a){et("error",`Received UnsubscribeApplied for unknown querySetId ${s}.`);return}const c={id:this.#d(),tag:"UnsubscribeApplied"},f=this.#c(c),p=n.value.rows?this.#x(n.value.rows,"delete"):[],v=this.#S(p,f),{event:y,...x}=f;a.emitter.emit("end",x),this.#s.subscriptions.delete(s),et("trace",()=>`Calling ${v.length} triggered row callbacks`);for(const R of v)R.cb();break}case"SubscriptionError":{const s=n.value.querySetId.id,a=n.value.requestId,c=Error(n.value.error),f={id:this.#d(),tag:"Error",value:c},v={...this.#c(f),event:c};if(a==null){et("error",`Disconnecting due to error for a previously applied subscription: ${n.value.error}`),this.disconnect();break}const y=this.#s.subscriptions.get(s);y?(y.emitter.emit("error",v,c),this.#s.subscriptions.delete(s)):et("error",`Received SubscriptionError for unknown querySetId ${s}:`,c);break}case"TransactionUpdate":{const s={id:this.#d(),tag:"Transaction"},a=this.#c(s),c=this.#k(a,n.value);et("trace",()=>`Calling ${c.length} triggered row callbacks`);for(const f of c)f.cb();break}case"ReducerResult":{const{requestId:s,result:a}=n.value;if(a.tag==="Ok"){const f=this.#y.get(s),p=this.#d(),v=f?{id:p,tag:"Reducer",value:{timestamp:n.value.timestamp,outcome:a,reducer:{name:f.name,args:f.args}}}:{id:p,tag:"Transaction"},y=this.#c(v),x=this.#k(y,a.value.transactionUpdate);et("trace",()=>`Calling ${x.length} triggered row callbacks`);for(const R of x)R.cb()}this.#y.delete(s);const c=this.#o.get(s);this.#o.delete(s),c?.(a);break}case"ProcedureResult":{const{status:s,requestId:a}=n.value,c=s.tag==="Returned"?{tag:"Ok",value:s.value}:{tag:"Err",value:s.value},f=this.#w.get(a);this.#w.delete(a),f?.(c);break}case"OneOffQueryResult":{et("warn","Received OneOffQueryResult but SDK does not expose one-off query APIs yet.");break}}}#A(r){this.#i=this.#i.then(()=>this.#B(r.data))}callReducer(r,n,s){const{promise:a,resolve:c,reject:f}=Promise.withResolvers(),p=this.#p(),v=xs.CallReducer({reducer:r,args:n,requestId:p,flags:0});return this.#m(v),s&&this.#y.set(p,{name:r,args:s}),this.#o.set(p,y=>{if(y.tag==="Ok"||y.tag==="OkEmpty")c();else if(y.tag==="Err"){const R=new ze(y.value).readString();f(new Km(R))}else y.tag==="InternalError"?f(new Wm(y.value)):f(new Error("Unexpected reducer result"))}),a}callReducerWithParams(r,n,s){const a=new Pe(1024);this.#f[r].serialize(a,s);const c=a.getBuffer();return this.callReducer(r,c,s)}callProcedure(r,n){const{promise:s,resolve:a,reject:c}=Promise.withResolvers(),f=this.#p(),p=xs.CallProcedure({procedure:r,args:n,requestId:f,flags:0});return this.#m(p),this.#w.set(f,v=>{v.tag==="Ok"?a(v.value):c(v.value)}),s}callProcedureWithParams(r,n,s,a){const c=new Pe(1024),{serializeArgs:f,deserializeReturn:p}=this.#h[r];f(c,s);const v=c.getBuffer();return this.callProcedure(r,v).then(y=>p(new ze(y)))}disconnect(){this.wsPromise.then(r=>r?.close())}on(r,n){this.#r.on(r,n)}off(r,n){this.#r.off(r,n)}onConnect(r){this.#r.on("connect",r)}onDisconnect(r){this.#r.on("disconnect",r)}onConnectError(r){this.#r.on("connectError",r)}removeOnConnect(r){this.#r.off("connect",r)}removeOnDisconnect(r){this.#r.off("disconnect",r)}removeOnConnectError(r){this.#r.off("connectError",r)}};function bw(r,n){const s=Object.create(null);for(const[a,c]of Object.entries(n))s[a]=Cw(a,c,c.tableDef(r,a));return{tables:s}}function Cw(r,n,s){const a=f=>n.rowType.algebraicType.value.elements[f].name,c=s.indexes.map(f=>{const p=f.accessorName;if(typeof p!="string"||p.length===0)throw new TypeError(`Index '${f.sourceName??""}' on table '${s.sourceName}' is missing accessor name`);const v=f.algorithm.tag==="Direct"?[f.algorithm.value]:f.algorithm.value,y=s.constraints.some(R=>R.data.tag==="Unique"&&R.data.value.columns.every(N=>v.includes(N))),x={BTree:"btree",Hash:"hash",Direct:"direct"}[f.algorithm.tag];return{name:p,unique:y,algorithm:x,columns:v.map(a)}});return{sourceName:n.tableName||r,accessorName:r,columns:n.rowType.row,rowType:n.rowSpacetimeType,indexes:n.idxs,constraints:s.constraints.map(f=>({name:f.sourceName,constraint:"unique",columns:f.data.value.columns.map(a)})),resolvedIndexes:c,tableDef:s,...s.isEvent?{isEvent:!0}:{}}}var Tw=class{#e=new Map;#t={typespace:{types:[]},tables:[],reducers:[],types:[],rowLevelSecurity:[],schedules:[],procedures:[],views:[],lifeCycleReducers:[],caseConversionPolicy:{tag:"SnakeCase"},explicitNames:{entries:[]}};get moduleDef(){return this.#t}rawModuleDefV10(){const r=[],n=a=>{a&&r.push(a)},s=this.#t;return n(s.typespace&&{tag:"Typespace",value:s.typespace}),n(s.types&&{tag:"Types",value:s.types}),n(s.tables&&{tag:"Tables",value:s.tables}),n(s.reducers&&{tag:"Reducers",value:s.reducers}),n(s.procedures&&{tag:"Procedures",value:s.procedures}),n(s.views&&{tag:"Views",value:s.views}),n(s.schedules&&{tag:"Schedules",value:s.schedules}),n(s.lifeCycleReducers&&{tag:"LifeCycleReducers",value:s.lifeCycleReducers}),n(s.rowLevelSecurity&&{tag:"RowLevelSecurity",value:s.rowLevelSecurity}),n(s.explicitNames&&{tag:"ExplicitNames",value:s.explicitNames}),n(s.caseConversionPolicy&&{tag:"CaseConversionPolicy",value:s.caseConversionPolicy}),{sections:r}}setCaseConversionPolicy(r){this.#t.caseConversionPolicy=r}get typespace(){return this.#t.typespace}resolveType(r){let n=r.algebraicType;for(;n.tag==="Ref";)n=this.typespace.types[n.value];return n}registerTypesRecursively(r){return r instanceof ki&&!Ew(r)||r instanceof gu||r instanceof wn?this.#n(r):r instanceof ca?new ca(this.registerTypesRecursively(r.value)):r instanceof pu?new pu(this.registerTypesRecursively(r.ok),this.registerTypesRecursively(r.err)):r instanceof hu?new hu(this.registerTypesRecursively(r.element)):r}#n(r){const n=r.algebraicType,s=r.typeName;if(s===void 0)throw new Error(`Missing type name for ${r.constructor.name??"TypeBuilder"} ${JSON.stringify(r)}`);let a=this.#e.get(n);if(a!=null)return a;const c=r instanceof wn||r instanceof ki?{tag:"Product",value:{elements:[]}}:{tag:"Sum",value:{variants:[]}};if(a=new Ay(this.#t.typespace.types.length),this.#t.typespace.types.push(c),this.#e.set(n,a),r instanceof wn)for(const[f,p]of Object.entries(r.row))c.value.elements.push({name:f,algebraicType:this.registerTypesRecursively(p.typeBuilder).algebraicType});else if(r instanceof ki)for(const[f,p]of Object.entries(r.elements))c.value.elements.push({name:f,algebraicType:this.registerTypesRecursively(p).algebraicType});else if(r instanceof gu)for(const[f,p]of Object.entries(r.variants))c.value.variants.push({name:f,algebraicType:this.registerTypesRecursively(p).algebraicType});return this.#t.types.push({sourceName:Uw(s),ty:a.ref,customOrdering:!0}),a}};function Ew(r){return r.typeName==null&&r.algebraicType.value.elements.length===0}function Uw(r){const n=r.split(".");return{sourceName:n.pop(),scope:n}}var Rw=class{constructor(r){this.schemaType=r}};function Nw(r){const n=new Tw;return new Rw(bw(n,r))}function Pw(r){return Object.fromEntries(r.map(n=>[n.accessorName,n]))}var Wt=d.enum("AlgebraicType",{Ref:d.u32(),get Sum(){return _v},get Product(){return _n},get Array(){return Wt},String:d.unit(),Bool:d.unit(),I8:d.unit(),U8:d.unit(),I16:d.unit(),U16:d.unit(),I32:d.unit(),U32:d.unit(),I64:d.unit(),U64:d.unit(),I128:d.unit(),U128:d.unit(),I256:d.unit(),U256:d.unit(),F32:d.unit(),F64:d.unit()}),Bw=d.enum("CaseConversionPolicy",{None:d.unit(),SnakeCase:d.unit()}),$h=d.enum("ExplicitNameEntry",{get Table(){return lu},get Function(){return lu},get Index(){return lu}}),Aw=d.object("ExplicitNames",{get entries(){return d.array($h)}}),Lh=d.enum("FunctionVisibility",{Private:d.unit(),ClientCallable:d.unit()}),Mw=d.object("HttpHeaderPair",{name:d.string(),value:d.byteArray()}),Vh=d.object("HttpHeaders",{get entries(){return d.array(Mw)}}),jw=d.enum("HttpMethod",{Get:d.unit(),Head:d.unit(),Post:d.unit(),Put:d.unit(),Delete:d.unit(),Connect:d.unit(),Options:d.unit(),Trace:d.unit(),Patch:d.unit(),Extension:d.string()});d.object("HttpRequest",{get method(){return jw},get headers(){return Vh},timeout:d.option(d.timeDuration()),uri:d.string(),get version(){return qh}});d.object("HttpResponse",{get headers(){return Vh},get version(){return qh},code:d.u16()});var qh=d.enum("HttpVersion",{Http09:d.unit(),Http10:d.unit(),Http11:d.unit(),Http2:d.unit(),Http3:d.unit()}),Ow=d.enum("IndexType",{BTree:d.unit(),Hash:d.unit()}),Hh=d.enum("Lifecycle",{Init:d.unit(),OnConnect:d.unit(),OnDisconnect:d.unit()}),Dw=d.enum("MiscModuleExport",{get TypeAlias(){return Iv}}),lu=d.object("NameMapping",{sourceName:d.string(),canonicalName:d.string()}),_n=d.object("ProductType",{get elements(){return d.array(Kh)}}),Kh=d.object("ProductTypeElement",{name:d.option(d.string()),get algebraicType(){return Wt}}),zw=d.object("RawColumnDefV8",{colName:d.string(),get colType(){return Wt}}),Fw=d.object("RawColumnDefaultValueV10",{colId:d.u16(),value:d.byteArray()}),$w=d.object("RawColumnDefaultValueV9",{table:d.string(),colId:d.u16(),value:d.byteArray()}),Wh=d.enum("RawConstraintDataV9",{get Unique(){return mv}}),Lw=d.object("RawConstraintDefV10",{sourceName:d.option(d.string()),get data(){return Wh}}),Vw=d.object("RawConstraintDefV8",{constraintName:d.string(),constraints:d.u8(),columns:d.array(d.u16())}),qw=d.object("RawConstraintDefV9",{name:d.option(d.string()),get data(){return Wh}}),Es=d.enum("RawIndexAlgorithm",{BTree:d.array(d.u16()),Hash:d.array(d.u16()),Direct:d.u16()}),Hw=d.object("RawIndexDefV10",{sourceName:d.option(d.string()),accessorName:d.option(d.string()),get algorithm(){return Es}}),Kw=d.object("RawIndexDefV8",{indexName:d.string(),isUnique:d.bool(),get indexType(){return Ow},columns:d.array(d.u16())}),Ww=d.object("RawIndexDefV9",{name:d.option(d.string()),accessorName:d.option(d.string()),get algorithm(){return Es}}),Qw=d.object("RawLifeCycleReducerDefV10",{get lifecycleSpec(){return Hh},functionName:d.string()}),Jw=d.enum("RawMiscModuleExportV9",{get ColumnDefaultValue(){return $w},get Procedure(){return tv},get View(){return wv}});d.enum("RawModuleDef",{get V8BackCompat(){return Yw},get V9(){return Zw},get V10(){return Gw}});var Gw=d.object("RawModuleDefV10",{get sections(){return d.array(Xw)}}),Xw=d.enum("RawModuleDefV10Section",{get Typespace(){return zu},get Types(){return d.array(pv)},get Tables(){return d.array(dv)},get Reducers(){return d.array(rv)},get Procedures(){return d.array(ev)},get Views(){return d.array(yv)},get Schedules(){return d.array(iv)},get LifeCycleReducers(){return d.array(Qw)},get RowLevelSecurity(){return d.array(Qh)},get CaseConversionPolicy(){return Bw},get ExplicitNames(){return Aw}}),Yw=d.object("RawModuleDefV8",{get typespace(){return zu},get tables(){return d.array(xv)},get reducers(){return d.array(vv)},get miscExports(){return d.array(Dw)}}),Zw=d.object("RawModuleDefV9",{get typespace(){return zu},get tables(){return d.array(hv)},get reducers(){return d.array(nv)},get types(){return d.array(gv)},get miscExports(){return d.array(Jw)},get rowLevelSecurity(){return d.array(Qh)}}),ev=d.object("RawProcedureDefV10",{sourceName:d.string(),get params(){return _n},get returnType(){return Wt},get visibility(){return Lh}}),tv=d.object("RawProcedureDefV9",{name:d.string(),get params(){return _n},get returnType(){return Wt}}),rv=d.object("RawReducerDefV10",{sourceName:d.string(),get params(){return _n},get visibility(){return Lh},get okReturnType(){return Wt},get errReturnType(){return Wt}}),nv=d.object("RawReducerDefV9",{name:d.string(),get params(){return _n},get lifecycle(){return d.option(Hh)}}),Qh=d.object("RawRowLevelSecurityDefV9",{sql:d.string()}),iv=d.object("RawScheduleDefV10",{sourceName:d.option(d.string()),tableName:d.string(),scheduleAtCol:d.u16(),functionName:d.string()}),sv=d.object("RawScheduleDefV9",{name:d.option(d.string()),reducerName:d.string(),scheduledAtColumn:d.u16()}),ov=d.object("RawScopedTypeNameV10",{scope:d.array(d.string()),sourceName:d.string()}),av=d.object("RawScopedTypeNameV9",{scope:d.array(d.string()),name:d.string()}),lv=d.object("RawSequenceDefV10",{sourceName:d.option(d.string()),column:d.u16(),start:d.option(d.i128()),minValue:d.option(d.i128()),maxValue:d.option(d.i128()),increment:d.i128()}),uv=d.object("RawSequenceDefV8",{sequenceName:d.string(),colPos:d.u16(),increment:d.i128(),start:d.option(d.i128()),minValue:d.option(d.i128()),maxValue:d.option(d.i128()),allocated:d.i128()}),cv=d.object("RawSequenceDefV9",{name:d.option(d.string()),column:d.u16(),start:d.option(d.i128()),minValue:d.option(d.i128()),maxValue:d.option(d.i128()),increment:d.i128()}),dv=d.object("RawTableDefV10",{sourceName:d.string(),productTypeRef:d.u32(),primaryKey:d.array(d.u16()),get indexes(){return d.array(Hw)},get constraints(){return d.array(Lw)},get sequences(){return d.array(lv)},get tableType(){return Gh},get tableAccess(){return Jh},get defaultValues(){return d.array(Fw)},isEvent:d.bool()}),fv=d.object("RawTableDefV8",{tableName:d.string(),get columns(){return d.array(zw)},get indexes(){return d.array(Kw)},get constraints(){return d.array(Vw)},get sequences(){return d.array(uv)},tableType:d.string(),tableAccess:d.string(),scheduled:d.option(d.string())}),hv=d.object("RawTableDefV9",{name:d.string(),productTypeRef:d.u32(),primaryKey:d.array(d.u16()),get indexes(){return d.array(Ww)},get constraints(){return d.array(qw)},get sequences(){return d.array(cv)},get schedule(){return d.option(sv)},get tableType(){return Gh},get tableAccess(){return Jh}}),pv=d.object("RawTypeDefV10",{get sourceName(){return ov},ty:d.u32(),customOrdering:d.bool()}),gv=d.object("RawTypeDefV9",{get name(){return av},ty:d.u32(),customOrdering:d.bool()}),mv=d.object("RawUniqueConstraintDataV9",{columns:d.array(d.u16())}),yv=d.object("RawViewDefV10",{sourceName:d.string(),index:d.u32(),isPublic:d.bool(),isAnonymous:d.bool(),get params(){return _n},get returnType(){return Wt}}),wv=d.object("RawViewDefV9",{name:d.string(),index:d.u32(),isPublic:d.bool(),isAnonymous:d.bool(),get params(){return _n},get returnType(){return Wt}}),vv=d.object("ReducerDef",{name:d.string(),get args(){return d.array(Kh)}}),_v=d.object("SumType",{get variants(){return d.array(Sv)}}),Sv=d.object("SumTypeVariant",{name:d.option(d.string()),get algebraicType(){return Wt}}),Jh=d.enum("TableAccess",{Public:d.unit(),Private:d.unit()}),xv=d.object("TableDesc",{get schema(){return fv},data:d.u32()}),Gh=d.enum("TableType",{System:d.unit(),User:d.unit()}),Iv=d.object("TypeAlias",{name:d.string(),ty:d.u32()}),zu=d.object("Typespace",{get types(){return d.array(Wt)}});d.enum("ViewResultHeader",{RowData:d.unit(),RawSql:d.string()});function dr(r,n,...s){const{name:a,public:c=!1,indexes:f=[],scheduled:p,event:v=!1}=r,y=new Map,x=[];n instanceof wn||(n=new wn(n)),n.algebraicType.value.elements.forEach((T,A)=>{y.set(T.name,A),x.push(T.name)});const R=[],N=[],j=[],O=[];let q;const Q=[];for(const[T,A]of Object.entries(n.row)){const L=A.columnMetadata;L.isPrimaryKey&&R.push(y.get(T));const J=L.isUnique||L.isPrimaryKey;if(L.indexType||J){const Y=L.indexType??"btree",ge=y.get(T);let me;switch(Y){case"btree":me=Es.BTree([ge]);break;case"hash":me=Es.Hash([ge]);break;case"direct":me=Es.Direct(ge);break}N.push({sourceName:void 0,accessorName:T,algorithm:me})}if(J&&j.push({sourceName:void 0,data:{tag:"Unique",value:{columns:[y.get(T)]}}}),L.isAutoIncrement&&O.push({sourceName:void 0,start:void 0,minValue:void 0,maxValue:void 0,column:y.get(T),increment:1n}),L.defaultValue){const Y=new Pe(16);A.serialize(Y,L.defaultValue),Q.push({colId:y.get(T),value:Y.getBuffer()})}if(p){const Y=A.typeBuilder.algebraicType;Uh.isScheduleAt(Y)&&(q=y.get(T))}}for(const T of f??[]){const A=T.accessor;if(typeof A!="string"||A.length===0){const J=a??"",Y=T.name??"";throw new TypeError(`Index '${Y}' on table '${J}' must define a non-empty 'accessor'`)}let L;switch(T.algorithm){case"btree":L={tag:"BTree",value:T.columns.map(J=>y.get(J))};break;case"hash":L={tag:"Hash",value:T.columns.map(J=>y.get(J))};break;case"direct":L={tag:"Direct",value:y.get(T.column)};break}N.push({sourceName:void 0,accessorName:A,algorithm:L,canonicalName:T.name})}for(const T of r.constraints??[])if(T.constraint==="unique"){const A={tag:"Unique",value:{columns:T.columns.map(L=>y.get(L))}};j.push({sourceName:T.name,data:A});continue}const $=n.algebraicType.value;return{rowType:n,tableName:a,rowSpacetimeType:$,tableDef:(T,A)=>{const L=a??A;n.typeName===void 0&&(n.typeName=Fm(L));for(const J of N){const ge=(J.algorithm.tag==="Direct"?[J.algorithm.value]:J.algorithm.value).map(Re=>x[Re]).join("_"),me=J.sourceName=`${A}_${ge}_idx_${J.algorithm.tag.toLowerCase()}`,{canonicalName:ue}=J;ue!==void 0&&T.moduleDef.explicitNames.entries.push($h.Index({sourceName:me,canonicalName:ue}))}return{sourceName:A,productTypeRef:T.registerTypesRecursively(n).ref,primaryKey:R,indexes:N,constraints:j,sequences:O,tableType:{tag:"User"},tableAccess:{tag:c?"Public":"Private"},defaultValues:Q,isEvent:v}},idxs:f,constraints:j,schedule:p&&q!==void 0?{scheduleAtCol:q,reducer:p}:void 0}}var kv=class{reducersType;constructor(r){this.reducersType=bv(r)}};function bv(r){return{reducers:r.map(a=>{const c=a.params.row;return{name:a.reducerName,accessorName:a.accessorName,params:c,paramsType:a.paramsSpacetimeType}})}}function Cv(...r){const n=r.length===1&&Array.isArray(r[0])?r[0]:r;return new kv(n)}function jt(r,n){const s={elements:Object.entries(n).map(([a,c])=>({name:a,algebraicType:"typeBuilder"in c?c.typeBuilder.algebraicType:c.algebraicType}))};return{reducerName:r,accessorName:Ch(r),params:new wn(n),paramsSpacetimeType:s,reducerDef:{name:r,params:s,lifecycle:void 0}}}function Tv(...r){return{procedures:r.length===1&&Array.isArray(r[0])?r[0]:r}}const Ev={name:d.string(),serverId:d.u64(),isVoice:d.bool()},Uv={name:d.string()},Rv={name:d.string(),channelId:d.u64(),parentMessageId:d.u64()},Nv={channelId:d.u64()},Pv={},Bv={username:d.string(),password:d.string()},Av={username:d.string(),password:d.string()},Mv={receiver:d.identity(),candidate:d.string(),channelId:d.u64()},jv={text:d.string(),channelId:d.u64(),threadId:d.option(d.u64())},Ov={receiver:d.identity(),sdp:d.string(),channelId:d.u64()},Dv={receiver:d.identity(),sdp:d.string(),channelId:d.u64()},zv={name:d.string()};d.object("Channel",{id:d.u64(),serverId:d.u64(),name:d.string(),get kind(){return Xh}});const Xh=d.enum("ChannelKind",{Text:d.unit(),Voice:d.unit()});d.object("IceCandidate",{sender:d.identity(),receiver:d.identity(),candidate:d.string(),channelId:d.u64()});d.object("Message",{id:d.u64(),sender:d.identity(),sent:d.timestamp(),text:d.string(),channelId:d.u64(),threadId:d.option(d.u64())});d.object("SdpAnswer",{sender:d.identity(),receiver:d.identity(),sdp:d.string(),channelId:d.u64()});d.object("SdpOffer",{sender:d.identity(),receiver:d.identity(),sdp:d.string(),channelId:d.u64()});d.object("Server",{id:d.u64(),name:d.string(),owner:d.option(d.identity())});d.object("Thread",{id:d.u64(),channelId:d.u64(),parentMessageId:d.u64(),name:d.string()});d.object("User",{identity:d.identity(),name:d.option(d.string()),online:d.bool(),issuer:d.option(d.string()),subject:d.option(d.string()),username:d.option(d.string()),password:d.option(d.string())});d.object("VoiceState",{identity:d.identity(),channelId:d.u64()});const Fv=d.row({id:d.u64().primaryKey(),serverId:d.u64().name("server_id"),name:d.string(),get kind(){return Xh}}),$v=d.row({sender:d.identity(),receiver:d.identity(),candidate:d.string(),channelId:d.u64().name("channel_id")}),Lv=d.row({id:d.u64().primaryKey(),sender:d.identity(),sent:d.timestamp(),text:d.string(),channelId:d.u64().name("channel_id"),threadId:d.option(d.u64()).name("thread_id")}),Vv=d.row({sender:d.identity(),receiver:d.identity(),sdp:d.string(),channelId:d.u64().name("channel_id")}),qv=d.row({sender:d.identity(),receiver:d.identity(),sdp:d.string(),channelId:d.u64().name("channel_id")}),Hv=d.row({id:d.u64().primaryKey(),name:d.string(),owner:d.option(d.identity())}),Kv=d.row({id:d.u64().primaryKey(),channelId:d.u64().name("channel_id"),parentMessageId:d.u64().name("parent_message_id"),name:d.string()}),Wv=d.row({identity:d.identity().primaryKey(),name:d.option(d.string()),online:d.bool(),issuer:d.option(d.string()),subject:d.option(d.string()),username:d.option(d.string()),password:d.option(d.string())}),Qv=d.row({identity:d.identity().primaryKey(),channelId:d.u64().name("channel_id")}),Yh=Nw({channel:dr({name:"channel",indexes:[{accessor:"id",name:"channel_id_idx_btree",algorithm:"btree",columns:["id"]},{accessor:"by_server_id",name:"channel_server_id_idx_btree",algorithm:"btree",columns:["serverId"]}],constraints:[{name:"channel_id_key",constraint:"unique",columns:["id"]}]},Fv),ice_candidate:dr({name:"ice_candidate",indexes:[{accessor:"by_receiver",name:"ice_candidate_receiver_idx_btree",algorithm:"btree",columns:["receiver"]}],constraints:[]},$v),message:dr({name:"message",indexes:[{accessor:"by_channel_id",name:"message_channel_id_idx_btree",algorithm:"btree",columns:["channelId"]},{accessor:"id",name:"message_id_idx_btree",algorithm:"btree",columns:["id"]},{accessor:"by_thread_id",name:"message_thread_id_idx_btree",algorithm:"btree",columns:["threadId"]}],constraints:[{name:"message_id_key",constraint:"unique",columns:["id"]}]},Lv),sdp_answer:dr({name:"sdp_answer",indexes:[{accessor:"by_receiver",name:"sdp_answer_receiver_idx_btree",algorithm:"btree",columns:["receiver"]}],constraints:[]},Vv),sdp_offer:dr({name:"sdp_offer",indexes:[{accessor:"by_receiver",name:"sdp_offer_receiver_idx_btree",algorithm:"btree",columns:["receiver"]}],constraints:[]},qv),server:dr({name:"server",indexes:[{accessor:"id",name:"server_id_idx_btree",algorithm:"btree",columns:["id"]}],constraints:[{name:"server_id_key",constraint:"unique",columns:["id"]}]},Hv),thread:dr({name:"thread",indexes:[{accessor:"by_channel_id",name:"thread_channel_id_idx_btree",algorithm:"btree",columns:["channelId"]},{accessor:"id",name:"thread_id_idx_btree",algorithm:"btree",columns:["id"]},{accessor:"parent_message_id",name:"thread_parent_message_id_idx_btree",algorithm:"btree",columns:["parentMessageId"]}],constraints:[{name:"thread_id_key",constraint:"unique",columns:["id"]},{name:"thread_parent_message_id_key",constraint:"unique",columns:["parentMessageId"]}]},Kv),user:dr({name:"user",indexes:[{accessor:"identity",name:"user_identity_idx_btree",algorithm:"btree",columns:["identity"]}],constraints:[{name:"user_identity_key",constraint:"unique",columns:["identity"]}]},Wv),voice_state:dr({name:"voice_state",indexes:[{accessor:"by_channel_id",name:"voice_state_channel_id_idx_btree",algorithm:"btree",columns:["channelId"]},{accessor:"identity",name:"voice_state_identity_idx_btree",algorithm:"btree",columns:["identity"]}],constraints:[{name:"voice_state_identity_key",constraint:"unique",columns:["identity"]}]},Qv)}),Zh=Cv(jt("create_channel",Ev),jt("create_server",Uv),jt("create_thread",Rv),jt("join_voice",Nv),jt("leave_voice",Pv),jt("login",Bv),jt("register",Av),jt("send_ice_candidate",Mv),jt("send_message",jv),jt("send_sdp_answer",Ov),jt("send_sdp_offer",Dv),jt("set_name",zv)),Jv=Tv(),Gv={versionInfo:{cliVersion:"2.1.0"},tables:Yh.schemaType.tables,reducers:Zh.reducersType.reducers,...Jv},fi=Nh(Yh.schemaType),fr=Pw(Zh.reducersType.reducers);class Xv extends Fh{}class Yv extends Sw{}class Fu extends kw{static builder=()=>new Yv(Gv,n=>new Fu(n));subscriptionBuilder=()=>new Xv(this)}var ep=class ia{__time_duration_micros__;static MICROS_PER_MILLIS=1000n;static getAlgebraicType(){return Be.Product({elements:[{name:"__time_duration_micros__",algebraicType:Be.I64}]})}static isTimeDuration(n){if(n.tag!=="Product")return!1;const s=n.value.elements;if(s.length!==1)return!1;const a=s[0];return a.name==="__time_duration_micros__"&&a.algebraicType.tag==="I64"}get micros(){return this.__time_duration_micros__}get millis(){return Number(this.micros/ia.MICROS_PER_MILLIS)}constructor(n){this.__time_duration_micros__=n}static fromMillis(n){return new ia(BigInt(n)*ia.MICROS_PER_MILLIS)}toString(){const n=this.micros,s=n<0?"-":"+",a=n<0?-n:n,c=a/1000000n,f=a%1000000n;return`${s}${c}.${String(f).padStart(6,"0")}`}},tp=class mn{__timestamp_micros_since_unix_epoch__;static MICROS_PER_MILLIS=1000n;get microsSinceUnixEpoch(){return this.__timestamp_micros_since_unix_epoch__}constructor(n){this.__timestamp_micros_since_unix_epoch__=n}static getAlgebraicType(){return Be.Product({elements:[{name:"__timestamp_micros_since_unix_epoch__",algebraicType:Be.I64}]})}static isTimestamp(n){if(n.tag!=="Product")return!1;const s=n.value.elements;if(s.length!==1)return!1;const a=s[0];return a.name==="__timestamp_micros_since_unix_epoch__"&&a.algebraicType.tag==="I64"}static UNIX_EPOCH=new mn(0n);static now(){return mn.fromDate(new Date)}toMillis(){return this.microsSinceUnixEpoch/1000n}static fromDate(n){const s=n.getTime(),a=BigInt(s)*mn.MICROS_PER_MILLIS;return new mn(a)}toDate(){const s=this.__timestamp_micros_since_unix_epoch__/mn.MICROS_PER_MILLIS;if(s>BigInt(Number.MAX_SAFE_INTEGER)||sBigInt(Number.MAX_SAFE_INTEGER)||s_t.MAX_UUID_BIGINT)throw new Error("Invalid UUID: must be between 0 and `MAX_UUID_BIGINT`");this.__uuid__=n}static fromRandomBytesV4(n){if(n.length!==16)throw new Error("UUID v4 requires 16 bytes");const s=new Uint8Array(n);return s[6]=s[6]&15|64,s[8]=s[8]&63|128,new _t(_t.bytesToBigInt(s))}static fromCounterV7(n,s,a){if(a.length!==4)throw new Error("`fromCounterV7` requires `randomBytes.length == 4`");if(n.value<0)throw new Error("`fromCounterV7` uuid `counter` must be non-negative");if(s.__timestamp_micros_since_unix_epoch__<0)throw new Error("`fromCounterV7` `timestamp` before unix epoch");const c=n.value;n.value=c+1&2147483647;const f=s.toMillis()&0xffffffffffffn,p=new Uint8Array(16);return p[0]=Number(f>>40n&0xffn),p[1]=Number(f>>32n&0xffn),p[2]=Number(f>>24n&0xffn),p[3]=Number(f>>16n&0xffn),p[4]=Number(f>>8n&0xffn),p[5]=Number(f&0xffn),p[7]=c>>>23&255,p[9]=c>>>15&255,p[10]=c>>>7&255,p[11]=(c&127)<<1&255,p[12]|=a[0]&127,p[13]=a[1],p[14]=a[2],p[15]=a[3],p[6]=p[6]&15|112,p[8]=p[8]&63|128,new _t(_t.bytesToBigInt(p))}static parse(n){const s=n.replace(/-/g,"");if(s.length!==32)throw new Error("Invalid hex UUID");let a=0n;for(let c=0;c<32;c+=2)a=a<<8n|BigInt(parseInt(s.slice(c,c+2),16));return new _t(a)}toString(){const s=[..._t.bigIntToBytes(this.__uuid__)].map(a=>a.toString(16).padStart(2,"0")).join("");return s.slice(0,8)+"-"+s.slice(8,12)+"-"+s.slice(12,16)+"-"+s.slice(16,20)+"-"+s.slice(20)}asBigInt(){return this.__uuid__}toBytes(){return _t.bigIntToBytes(this.__uuid__)}static bytesToBigInt(n){let s=0n;for(const a of n)s=s<<8n|BigInt(a);return s}static bigIntToBytes(n){const s=new Uint8Array(16);for(let a=15;a>=0;a--)s[a]=Number(n&0xffn),n>>=8n;return s}getVersion(){const n=this.toBytes()[6]>>4&15;switch(n){case 4:return"V4";case 7:return"V7";default:if(this==_t.NIL)return"Nil";if(this==_t.MAX)return"Max";throw new Error(`Unsupported UUID version: ${n}`)}}getCounter(){const n=this.toBytes(),s=n[7],a=n[9],c=n[10],f=n[11]>>>1;return s<<23|a<<15|c<<7|f|0}compareTo(n){return this.__uuid__n.__uuid__?1:0}static getAlgebraicType(){return Be.Product({elements:[{name:"__uuid__",algebraicType:Be.U128}]})}},Ze=class{view;offset=0;constructor(r){this.view=r instanceof DataView?r:new DataView(r.buffer,r.byteOffset,r.byteLength),this.offset=0}reset(r){this.view=r,this.offset=0}get remaining(){return this.view.byteLength-this.offset}#e(r){if(this.offset+r>this.view.byteLength)throw new RangeError(`Tried to read ${r} byte(s) at relative offset ${this.offset}, but only ${this.remaining} byte(s) remain`)}readUInt8Array(){const r=this.readU32();return this.#e(r),this.readBytes(r)}readBool(){const r=this.view.getUint8(this.offset);return this.offset+=1,r!==0}readByte(){const r=this.view.getUint8(this.offset);return this.offset+=1,r}readBytes(r){const n=new Uint8Array(this.view.buffer,this.view.byteOffset+this.offset,r);return this.offset+=r,n}readI8(){const r=this.view.getInt8(this.offset);return this.offset+=1,r}readU8(){return this.readByte()}readI16(){const r=this.view.getInt16(this.offset,!0);return this.offset+=2,r}readU16(){const r=this.view.getUint16(this.offset,!0);return this.offset+=2,r}readI32(){const r=this.view.getInt32(this.offset,!0);return this.offset+=4,r}readU32(){const r=this.view.getUint32(this.offset,!0);return this.offset+=4,r}readI64(){const r=this.view.getBigInt64(this.offset,!0);return this.offset+=8,r}readU64(){const r=this.view.getBigUint64(this.offset,!0);return this.offset+=8,r}readU128(){const r=this.view.getBigUint64(this.offset,!0),n=this.view.getBigUint64(this.offset+8,!0);return this.offset+=16,(n<>BigInt(64);this.view.setBigUint64(this.offset,n,!0),this.view.setBigUint64(this.offset+8,s,!0),this.offset+=16}writeI128(r){this.expandBuffer(16);const n=r&BigInt("0xFFFFFFFFFFFFFFFF"),s=r>>BigInt(64);this.view.setBigInt64(this.offset,n,!0),this.view.setBigInt64(this.offset+8,s,!0),this.offset+=16}writeU256(r){this.expandBuffer(32);const n=BigInt("0xFFFFFFFFFFFFFFFF"),s=r&n,a=r>>BigInt(64)&n,c=r>>BigInt(128)&n,f=r>>BigInt(192);this.view.setBigUint64(this.offset+0,s,!0),this.view.setBigUint64(this.offset+8,a,!0),this.view.setBigUint64(this.offset+16,c,!0),this.view.setBigUint64(this.offset+24,f,!0),this.offset+=32}writeI256(r){this.expandBuffer(32);const n=BigInt("0xFFFFFFFFFFFFFFFF"),s=r&n,a=r>>BigInt(64)&n,c=r>>BigInt(128)&n,f=r>>BigInt(192);this.view.setBigUint64(this.offset+0,s,!0),this.view.setBigUint64(this.offset+8,a,!0),this.view.setBigUint64(this.offset+16,c,!0),this.view.setBigInt64(this.offset+24,f,!0),this.offset+=32}writeF32(r){this.expandBuffer(4),this.view.setFloat32(this.offset,r,!0),this.offset+=4}writeF64(r){this.expandBuffer(8),this.view.setFloat64(this.offset,r,!0),this.offset+=8}writeString(r){const s=new TextEncoder().encode(r);this.writeUInt8Array(s)}};function rp(r){return Array.prototype.map.call(r.reverse(),n=>("00"+n.toString(16)).slice(-2)).join("")}function r_(r){if(r.length!=16)throw new Error(`Uint8Array is not 16 bytes long: ${r}`);return new Ze(r).readU128()}function n_(r){if(r.length!=32)throw new Error(`Uint8Array is not 32 bytes long: [${r}]`);return new Ze(r).readU256()}function np(r){r.startsWith("0x")&&(r=r.slice(2));const n=r.match(/.{1,2}/g)||[];return Uint8Array.from(n.map(a=>parseInt(a,16))).reverse()}function i_(r){return r_(np(r))}function s_(r){return n_(np(r))}function ip(r){const n=new Ke(16);return n.writeU128(r),n.getBuffer()}function o_(r){return rp(ip(r))}function sp(r){const n=new Ke(32);return n.writeU256(r),n.getBuffer()}function a_(r){return rp(sp(r))}var ah=Object.hasOwn,l_=class Tu{__identity__;constructor(n){this.__identity__=typeof n=="string"?s_(n):n}static getAlgebraicType(){return Be.Product({elements:[{name:"__identity__",algebraicType:Be.U256}]})}isEqual(n){return this.toHexString()===n.toHexString()}equals(n){return this.isEqual(n)}toHexString(){return a_(this.__identity__)}toUint8Array(){return sp(this.__identity__)}static fromString(n){return new Tu(n)}static zero(){return new Tu(0n)}toString(){return this.toHexString()}},Us=new Map,Rs=new Map,Be={Ref:r=>({tag:"Ref",value:r}),Sum:r=>({tag:"Sum",value:r}),Product:r=>({tag:"Product",value:r}),Array:r=>({tag:"Array",value:r}),String:{tag:"String"},Bool:{tag:"Bool"},I8:{tag:"I8"},U8:{tag:"U8"},I16:{tag:"I16"},U16:{tag:"U16"},I32:{tag:"I32"},U32:{tag:"U32"},I64:{tag:"I64"},U64:{tag:"U64"},I128:{tag:"I128"},U128:{tag:"U128"},I256:{tag:"I256"},U256:{tag:"U256"},F32:{tag:"F32"},F64:{tag:"F64"},makeSerializer(r,n){if(r.tag==="Ref"){if(!n)throw new Error("cannot serialize refs without a typespace");for(;r.tag==="Ref";)r=n.types[r.value]}switch(r.tag){case"Product":return Ns.makeSerializer(r.value,n);case"Sum":return fa.makeSerializer(r.value,n);case"Array":if(r.value.tag==="U8")return u_;{const s=Be.makeSerializer(r.value,n);return(a,c)=>{a.writeU32(c.length);for(const f of c)s(a,f)}}default:return op[r.tag]}},serializeValue(r,n,s,a){Be.makeSerializer(n,a)(r,s)},makeDeserializer(r,n){if(r.tag==="Ref"){if(!n)throw new Error("cannot deserialize refs without a typespace");for(;r.tag==="Ref";)r=n.types[r.value]}switch(r.tag){case"Product":return Ns.makeDeserializer(r.value,n);case"Sum":return fa.makeDeserializer(r.value,n);case"Array":if(r.value.tag==="U8")return c_;{const s=Be.makeDeserializer(r.value,n);return a=>{const c=a.readU32(),f=Array(c);for(let p=0;pr.elements.every(({algebraicType:n})=>d_.has(n.tag)),f_=r=>r.elements.reduce((n,{algebraicType:s})=>n+Ii[s.tag],0),Xo={Bool:"Uint8",I8:"Int8",U8:"Uint8",I16:"Int16",U16:"Uint16",I32:"Int32",U32:"Uint32",I64:"BigInt64",U64:"BigUint64",F32:"Float32",F64:"Float64"},sa={__time_duration_micros__:r=>new ep(r.readI64()),__timestamp_micros_since_unix_epoch__:r=>new tp(r.readI64()),__identity__:r=>new l_(r.readU256()),__connection_id__:r=>new $u(r.readU128()),__uuid__:r=>new Zv(r.readU128())};Object.freeze(sa);var h_=()=>({}),uh=r=>{let n;switch(r.algebraicType.tag){case"String":n="''";break;case"Bool":n="false";break;case"I8":case"U8":case"I16":case"U16":case"I32":case"U32":n="0";break;case"I64":case"U64":case"I128":case"U128":case"I256":case"U256":n="0n";break;case"F32":case"F64":n="0.0";break;default:n="undefined"}return`${r.name}: ${n}`},Ns={makeSerializer(r,n){let s=Us.get(r);if(s!=null)return s;if(lh(r)){const p=`"use strict"; +writer.expandBuffer(${f_(r)}); +const view = writer.view; +${r.elements.map(({name:v,algebraicType:{tag:y}})=>y in Xo?`view.set${Xo[y]}(writer.offset, value.${v}, ${Ii[y]>1?"true":""}); +writer.offset += ${Ii[y]};`:`writer.write${y}(value.${v});`).join(` +`)}`;return s=Function("writer","value",p),Us.set(r,s),s}const a={},c=`"use strict"; +`+r.elements.map(f=>`this.${f.name}(writer, value.${f.name});`).join(` +`);s=Function("writer","value",c).bind(a),Us.set(r,s);for(const{name:f,algebraicType:p}of r.elements)a[f]=Be.makeSerializer(p,n);return Object.freeze(a),s},serializeValue(r,n,s,a){Ns.makeSerializer(n,a)(r,s)},makeDeserializer(r,n){switch(r.elements.length){case 0:return h_;case 1:{const c=r.elements[0].name;if(ah(sa,c))return sa[c]}}let s=Rs.get(r);if(s!=null)return s;if(lh(r)){const c=`"use strict"; +const result = { ${r.elements.map(uh).join(", ")} }; +const view = reader.view; +${r.elements.map(({name:f,algebraicType:{tag:p}})=>p in Xo?p==="Bool"?`result.${f} = view.getUint8(reader.offset) !== 0; +reader.offset += 1;`:`result.${f} = view.get${Xo[p]}(reader.offset, ${Ii[p]>1?"true":""}); +reader.offset += ${Ii[p]};`:`result.${f} = reader.read${p}();`).join(` +`)} +return result;`;return s=Function("reader",c),Rs.set(r,s),s}const a={};s=Function("reader",`"use strict"; +const result = { ${r.elements.map(uh).join(", ")} }; +${r.elements.map(({name:c})=>`result.${c} = this.${c}(reader);`).join(` +`)} +return result;`).bind(a),Rs.set(r,s);for(const{name:c,algebraicType:f}of r.elements)a[c]=Be.makeDeserializer(f,n);return Object.freeze(a),s},deserializeValue(r,n,s){return Ns.makeDeserializer(n,s)(r)},intoMapKey(r,n){if(r.elements.length===1){const a=r.elements[0].name;if(ah(sa,a))return n[a]}const s=new Ke(10);return Be.serializeValue(s,Be.Product(r),n),s.toBase64()}},fa={makeSerializer(r,n){if(r.variants.length==2&&r.variants[0].name==="some"&&r.variants[1].name==="none"){const s=Be.makeSerializer(r.variants[0].algebraicType,n);return(a,c)=>{c!=null?(a.writeByte(0),s(a,c)):a.writeByte(1)}}else if(r.variants.length==2&&r.variants[0].name==="ok"&&r.variants[1].name==="err"){const s=Be.makeSerializer(r.variants[0].algebraicType,n),a=Be.makeSerializer(r.variants[0].algebraicType,n);return(c,f)=>{if("ok"in f)c.writeU8(0),s(c,f.ok);else if("err"in f)c.writeU8(1),a(c,f.err);else throw new TypeError("could not serialize result: object had neither a `ok` nor an `err` field")}}else{let s=Us.get(r);if(s!=null)return s;const a={},c=`switch (value.tag) { +${r.variants.map(({name:f},p)=>` case ${JSON.stringify(f)}: + writer.writeByte(${p}); + return this.${f}(writer, value.value);`).join(` +`)} + default: + throw new TypeError( + \`Could not serialize sum type; unknown tag \${value.tag}\` + ) +} +`;s=Function("writer","value",c).bind(a),Us.set(r,s);for(const{name:f,algebraicType:p}of r.variants)a[f]=Be.makeSerializer(p,n);return Object.freeze(a),s}},serializeValue(r,n,s,a){fa.makeSerializer(n,a)(r,s)},makeDeserializer(r,n){if(r.variants.length==2&&r.variants[0].name==="some"&&r.variants[1].name==="none"){const s=Be.makeDeserializer(r.variants[0].algebraicType,n);return a=>{const c=a.readU8();if(c===0)return s(a);if(c===1)return;throw`Can't deserialize an option type, couldn't find ${c} tag`}}else if(r.variants.length==2&&r.variants[0].name==="ok"&&r.variants[1].name==="err"){const s=Be.makeDeserializer(r.variants[0].algebraicType,n),a=Be.makeDeserializer(r.variants[1].algebraicType,n);return c=>{const f=c.readByte();if(f===0)return{ok:s(c)};if(f===1)return{err:a(c)};throw`Can't deserialize a result type, couldn't find ${f} tag`}}else{let s=Rs.get(r);if(s!=null)return s;const a={};s=Function("reader",`switch (reader.readU8()) { +${r.variants.map(({name:c},f)=>`case ${f}: return { tag: ${JSON.stringify(c)}, value: this.${c}(reader) };`).join(` +`)} }`).bind(a),Rs.set(r,s);for(const{name:c,algebraicType:f}of r.variants)a[c]=Be.makeDeserializer(f,n);return Object.freeze(a),s}},deserializeValue(r,n,s){return fa.makeDeserializer(n,s)(r)}},$u=class oa{__connection_id__;constructor(n){this.__connection_id__=n}static getAlgebraicType(){return Be.Product({elements:[{name:"__connection_id__",algebraicType:Be.U128}]})}isZero(){return this.__connection_id__===BigInt(0)}static nullIfZero(n){return n.isZero()?null:n}static random(){function n(){return Math.floor(Math.random()*255)}let s=BigInt(0);for(let a=0;a<16;a++)s=s<Ot(r.right,n);case"gte":return Ot(r.left,n)>=Ot(r.right,n);case"lt":return Ot(r.left,n)aa(s,n));case"or":return r.clauses.some(s=>aa(s,n));case"not":return!aa(r.clause,n)}}function Ot(r,n){return g_(r)?ch(r.value):ch(n[r.column])}function m_(r){return!!r&&typeof r=="object"&&typeof r.toHexString=="function"}function y_(r){return!r||typeof r!="object"?!1:r instanceof tp?!0:typeof r.__timestamp_micros_since_unix_epoch__=="bigint"}function ch(r){return m_(r)?r.toHexString():y_(r)?r.__timestamp_micros_since_unix_epoch__:r}function w_(r){if(r.table)return r.table.accessorName;if(r.accessorName)return r.accessorName;if(r.sourceQuery)return r.sourceQuery.table.accessorName;throw new Error("Cannot extract accessor name from query")}function v_(r){if(r.whereClause)return r.whereClause}var lp=ae.createContext(void 0);function Lu(){const r=ae.useContext(lp);if(!r)throw new Error("useSpacetimeDB must be used within a SpacetimeDBProvider component. Did you forget to add a `SpacetimeDBProvider` to your component tree?");return r}function __(){return{isActive:!1,identity:void 0,token:void 0,connectionId:$u.random(),connectionError:void 0}}var S_=class up{#e=new Map;static getKey(n,s){return`${n}::${s}`}getKey(n,s){return up.getKey(n,s)}#t(n){const s=this.#e.get(n);if(s)return s;const a={connection:void 0,refCount:0,state:__(),listeners:new Set,pendingRelease:null};return this.#e.set(n,a),a}#n(n){for(const s of n.listeners)s()}retain(n,s){const a=this.#t(n);if(a.pendingRelease&&(clearTimeout(a.pendingRelease),a.pendingRelease=null),a.refCount+=1,a.connection)return a.connection;const c=s.build();a.connection=c;const f=p=>{a.state={...a.state,...p},this.#n(a)};return f({isActive:c.isActive,identity:c.identity,token:c.token,connectionId:c.connectionId,connectionError:void 0}),a.onConnect=p=>{f({isActive:p.isActive,identity:p.identity,token:p.token,connectionId:p.connectionId,connectionError:void 0})},a.onDisconnect=(p,v)=>{f({isActive:p.isActive,connectionError:v??void 0})},a.onConnectError=(p,v)=>{f({isActive:p.isActive,connectionError:v})},s.onConnect(a.onConnect),s.onDisconnect(a.onDisconnect),s.onConnectError(a.onConnectError),c}release(n){const s=this.#e.get(n);s&&(s.refCount-=1,!(s.refCount>0||s.pendingRelease)&&(s.pendingRelease=setTimeout(()=>{s.pendingRelease=null,!(s.refCount>0)&&(s.connection&&(s.onConnect&&s.connection.removeOnConnect(s.onConnect),s.onDisconnect&&s.connection.removeOnDisconnect(s.onDisconnect),s.onConnectError&&s.connection.removeOnConnectError(s.onConnectError),s.connection.disconnect()),this.#e.delete(n))},0)))}subscribe(n,s){const a=this.#t(n);return a.listeners.add(s),()=>{a.listeners.delete(s),a.refCount<=0&&a.listeners.size===0&&!a.connection&&this.#e.delete(n)}}getSnapshot(n){return this.#e.get(n)?.state}getConnection(n){return this.#e.get(n)?.connection??null}},hi=new S_;function x_({connectionBuilder:r,children:n}){const s=r.getUri(),a=r.getModuleName(),c=ae.useMemo(()=>hi.getKey(s,a),[s,a]),f=ae.useRef({isActive:!1,identity:void 0,token:void 0,connectionId:$u.random(),connectionError:void 0}),p=ae.useCallback(j=>hi.subscribe(c,j),[c]),v=ae.useCallback(()=>hi.getSnapshot(c)??f.current,[c]),y=ae.useCallback(()=>f.current,[]),x=ae.useSyncExternalStore(p,v,y),R=ae.useCallback(()=>hi.getConnection(c),[c]),N=ae.useMemo(()=>({...x,getConnection:R}),[x,R]);return ae.useEffect(()=>(hi.retain(c,r),()=>{hi.release(c)}),[c,r]),ae.createElement(lp.Provider,{value:N},n)}function I_(r,n,s){if(!r)return"stayIn";const a=Ps(r,n),c=Ps(r,s);return a&&!c?"leave":!a&&c?"enter":a&&c?"stayIn":"stayOut"}function pi(r,n){const s=w_(r),a=v_(r),[c,f]=ae.useState(!1);let p;try{p=Lu()}catch{throw new Error("Could not find SpacetimeDB client! Did you forget to add a `SpacetimeDBProvider`? `useTable` must be used in the React component tree under a `SpacetimeDBProvider` component.")}const v=p_(r),y=ae.useRef(null),x=ae.useRef(null),R=ae.useCallback(()=>{const O=p.getConnection();if(!O)return[[],!1];const q=O.db[s];return[a?Array.from(q.iter()).filter($=>Ps(a,$)):Array.from(q.iter()),c]},[p,s,v,c]);ae.useEffect(()=>{x.current=null},[R]),ae.useEffect(()=>{const O=p.getConnection();if(p.isActive&&O){const q=O.subscriptionBuilder().onApplied(()=>{f(!0)}).subscribe(v);return()=>{q.unsubscribe()}}},[v,p.isActive,p]);const N=ae.useCallback(O=>{const q=(A,L)=>{a&&!Ps(a,L)||A.event.id!==y.current&&(y.current=A.event.id,x.current=R(),O())},Q=(A,L)=>{a&&!Ps(a,L)||A.event.id!==y.current&&(y.current=A.event.id,x.current=R(),O())},$=(A,L,J)=>{switch(I_(a,L,J)){case"leave":break;case"enter":break;case"stayIn":break;case"stayOut":return}A.event.id!==y.current&&(y.current=A.event.id,x.current=R(),O())},fe=p.getConnection();if(!fe)return()=>{};const T=fe.db[s];return T.onInsert(q),T.onDelete(Q),T.onUpdate?.($),()=>{T.removeOnInsert(q),T.removeOnDelete(Q),T.removeOnUpdate?.($)}},[p,s,v,R,n?.onDelete,n?.onInsert,n?.onUpdate]),j=ae.useCallback(()=>(x.current||(x.current=R()),x.current),[R]);return ae.useSyncExternalStore(N,j,j)}function hr(r){const{getConnection:n,isActive:s}=Lu(),a=r.accessorName,c=ae.useRef([]);return ae.useEffect(()=>{const f=n();if(!f)return;const p=f.reducers[a];if(c.current.length){const v=c.current.splice(0);for(const y of v)p(...y.params).then(y.resolve,y.reject)}},[n,a,s]),ae.useCallback((...f)=>{const p=n();if(!p)return new Promise((y,x)=>{c.current.push({params:f,resolve:y,reject:x})});const v=p.reducers[a];return v(...f)},[n,a])}class ks extends Error{}ks.prototype.name="InvalidTokenError";function k_(r){return decodeURIComponent(atob(r).replace(/(.)/g,(n,s)=>{let a=s.charCodeAt(0).toString(16).toUpperCase();return a.length<2&&(a="0"+a),"%"+a}))}function b_(r){let n=r.replace(/-/g,"+").replace(/_/g,"/");switch(n.length%4){case 0:break;case 2:n+="==";break;case 3:n+="=";break;default:throw new Error("base64 string is not of the correct length")}try{return k_(n)}catch{return atob(n)}}function C_(r,n){if(typeof r!="string")throw new ks("Invalid token specified: must be a string");n||(n={});const s=n.header===!0?0:1,a=r.split(".")[s];if(typeof a!="string")throw new ks(`Invalid token specified: missing part #${s+1}`);let c;try{c=b_(a)}catch(f){throw new ks(`Invalid token specified: invalid base64 for part #${s+1} (${f.message})`)}try{return JSON.parse(c)}catch(f){throw new ks(`Invalid token specified: invalid json for part #${s+1} (${f.message})`)}}var T_={debug:()=>{},info:()=>{},warn:()=>{},error:()=>{}},er,tr,ha=(r=>(r[r.NONE=0]="NONE",r[r.ERROR=1]="ERROR",r[r.WARN=2]="WARN",r[r.INFO=3]="INFO",r[r.DEBUG=4]="DEBUG",r))(ha||{});(r=>{function n(){er=3,tr=T_}r.reset=n;function s(c){if(!(0<=c&&c<=4))throw new Error("Invalid log level");er=c}r.setLevel=s;function a(c){tr=c}r.setLogger=a})(ha||(ha={}));var Se=class Zt{constructor(n){this._name=n}debug(...n){er>=4&&tr.debug(Zt._format(this._name,this._method),...n)}info(...n){er>=3&&tr.info(Zt._format(this._name,this._method),...n)}warn(...n){er>=2&&tr.warn(Zt._format(this._name,this._method),...n)}error(...n){er>=1&&tr.error(Zt._format(this._name,this._method),...n)}throw(n){throw this.error(n),n}create(n){const s=Object.create(this);return s._method=n,s.debug("begin"),s}static createStatic(n,s){const a=new Zt(`${n}.${s}`);return a.debug("begin"),a}static _format(n,s){const a=`[${n}]`;return s?`${a} ${s}:`:a}static debug(n,...s){er>=4&&tr.debug(Zt._format(n),...s)}static info(n,...s){er>=3&&tr.info(Zt._format(n),...s)}static warn(n,...s){er>=2&&tr.warn(Zt._format(n),...s)}static error(n,...s){er>=1&&tr.error(Zt._format(n),...s)}};ha.reset();var Ms=class{static decode(r){try{return C_(r)}catch(n){throw Se.error("JwtUtils.decode",n),n}}static async generateSignedJwt(r,n,s){const a=Je.encodeBase64Url(new TextEncoder().encode(JSON.stringify(r))),c=Je.encodeBase64Url(new TextEncoder().encode(JSON.stringify(n))),f=`${a}.${c}`,p=await window.crypto.subtle.sign({name:"ECDSA",hash:{name:"SHA-256"}},s,new TextEncoder().encode(f)),v=Je.encodeBase64Url(new Uint8Array(p));return`${f}.${v}`}static async generateSignedJwtWithHmac(r,n,s){const a=Je.encodeBase64Url(new TextEncoder().encode(JSON.stringify(r))),c=Je.encodeBase64Url(new TextEncoder().encode(JSON.stringify(n))),f=`${a}.${c}`,p=await window.crypto.subtle.sign("HMAC",s,new TextEncoder().encode(f)),v=Je.encodeBase64Url(new Uint8Array(p));return`${f}.${v}`}},E_="10000000-1000-4000-8000-100000000000",Eu=r=>btoa([...new Uint8Array(r)].map(n=>String.fromCharCode(n)).join("")),cp=class Kt{static _randomWord(){const n=new Uint32Array(1);return crypto.getRandomValues(n),n[0]}static generateUUIDv4(){return E_.replace(/[018]/g,s=>(+s^Kt._randomWord()&15>>+s/4).toString(16)).replace(/-/g,"")}static generateCodeVerifier(){return Kt.generateUUIDv4()+Kt.generateUUIDv4()+Kt.generateUUIDv4()}static async generateCodeChallenge(n){if(!crypto.subtle)throw new Error("Crypto.subtle is available only in secure contexts (HTTPS).");try{const a=new TextEncoder().encode(n),c=await crypto.subtle.digest("SHA-256",a);return Eu(c).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}catch(s){throw Se.error("CryptoUtils.generateCodeChallenge",s),s}}static generateBasicAuth(n,s){const c=new TextEncoder().encode([n,s].join(":"));return Eu(c)}static async hash(n,s){const a=new TextEncoder().encode(s),c=await crypto.subtle.digest(n,a);return new Uint8Array(c)}static async customCalculateJwkThumbprint(n){let s;switch(n.kty){case"RSA":s={e:n.e,kty:n.kty,n:n.n};break;case"EC":s={crv:n.crv,kty:n.kty,x:n.x,y:n.y};break;case"OKP":s={crv:n.crv,kty:n.kty,x:n.x};break;case"oct":s={crv:n.k,kty:n.kty};break;default:throw new Error("Unknown jwk type")}const a=await Kt.hash("SHA-256",JSON.stringify(s));return Kt.encodeBase64Url(a)}static async generateDPoPProof({url:n,accessToken:s,httpMethod:a,keyPair:c,nonce:f}){let p,v;const y={jti:window.crypto.randomUUID(),htm:a??"GET",htu:n,iat:Math.floor(Date.now()/1e3)};s&&(p=await Kt.hash("SHA-256",s),v=Kt.encodeBase64Url(p),y.ath=v),f&&(y.nonce=f);try{const x=await crypto.subtle.exportKey("jwk",c.publicKey),R={alg:"ES256",typ:"dpop+jwt",jwk:{crv:x.crv,kty:x.kty,x:x.x,y:x.y}};return await Ms.generateSignedJwt(R,y,c.privateKey)}catch(x){throw x instanceof TypeError?new Error(`Error exporting dpop public key: ${x.message}`):x}}static async generateDPoPJkt(n){try{const s=await crypto.subtle.exportKey("jwk",n.publicKey);return await Kt.customCalculateJwkThumbprint(s)}catch(s){throw s instanceof TypeError?new Error(`Could not retrieve dpop keys from storage: ${s.message}`):s}}static async generateDPoPKeys(){return await window.crypto.subtle.generateKey({name:"ECDSA",namedCurve:"P-256"},!1,["sign","verify"])}static async generateClientAssertionJwt(n,s,a,c="HS256"){const f=Math.floor(Date.now()/1e3),p={alg:c,typ:"JWT"},v={iss:n,sub:n,aud:a,jti:Kt.generateUUIDv4(),exp:f+300,iat:f},x={HS256:"SHA-256",HS384:"SHA-384",HS512:"SHA-512"}[c];if(!x)throw new Error(`Unsupported algorithm: ${c}. Supported algorithms are: HS256, HS384, HS512`);const R=new TextEncoder,N=await crypto.subtle.importKey("raw",R.encode(s),{name:"HMAC",hash:x},!1,["sign"]);return await Ms.generateSignedJwtWithHmac(p,v,N)}};cp.encodeBase64Url=r=>Eu(r).replace(/=/g,"").replace(/\+/g,"-").replace(/\//g,"_");var Je=cp,Or=class{constructor(r){this._name=r,this._callbacks=[],this._logger=new Se(`Event('${this._name}')`)}addHandler(r){return this._callbacks.push(r),()=>this.removeHandler(r)}removeHandler(r){const n=this._callbacks.lastIndexOf(r);n>=0&&this._callbacks.splice(n,1)}async raise(...r){this._logger.debug("raise:",...r);for(const n of this._callbacks)await n(...r)}},dh=class{static center({...r}){var n,s,a;return r.width==null&&(r.width=(n=[800,720,600,480].find(c=>c<=window.outerWidth/1.618))!=null?n:360),(s=r.left)!=null||(r.left=Math.max(0,Math.round(window.screenX+(window.outerWidth-r.width)/2))),r.height!=null&&((a=r.top)!=null||(r.top=Math.max(0,Math.round(window.screenY+(window.outerHeight-r.height)/2)))),r}static serialize(r){return Object.entries(r).filter(([,n])=>n!=null).map(([n,s])=>`${n}=${typeof s!="boolean"?s:s?"yes":"no"}`).join(",")}},gr=class la extends Or{constructor(){super(...arguments),this._logger=new Se(`Timer('${this._name}')`),this._timerHandle=null,this._expiration=0,this._callback=()=>{const n=this._expiration-la.getEpochTime();this._logger.debug("timer completes in",n),this._expiration<=la.getEpochTime()&&(this.cancel(),super.raise())}}static getEpochTime(){return Math.floor(Date.now()/1e3)}init(n){const s=this._logger.create("init");n=Math.max(Math.floor(n),1);const a=la.getEpochTime()+n;if(this.expiration===a&&this._timerHandle){s.debug("skipping since already initialized for expiration at",this.expiration);return}this.cancel(),s.debug("using duration",n),this._expiration=a;const c=Math.min(n,5);this._timerHandle=setInterval(this._callback,c*1e3)}get expiration(){return this._expiration}cancel(){this._logger.create("cancel"),this._timerHandle&&(clearInterval(this._timerHandle),this._timerHandle=null)}},Uu=class{static readParams(r,n="query"){if(!r)throw new TypeError("Invalid URL");const a=new URL(r,"http://127.0.0.1")[n==="fragment"?"hash":"search"];return new URLSearchParams(a.slice(1))}},Ti=";",vn=class extends Error{constructor(r,n){var s,a,c;if(super(r.error_description||r.error||""),this.form=n,this.name="ErrorResponse",!r.error)throw Se.error("ErrorResponse","No error passed"),new Error("No error passed");this.error=r.error,this.error_description=(s=r.error_description)!=null?s:null,this.error_uri=(a=r.error_uri)!=null?a:null,this.state=r.userState,this.session_state=(c=r.session_state)!=null?c:null,this.url_state=r.url_state}},Vu=class extends Error{constructor(r){super(r),this.name="ErrorTimeout"}},U_=class{constructor(r){this._logger=new Se("AccessTokenEvents"),this._expiringTimer=new gr("Access token expiring"),this._expiredTimer=new gr("Access token expired"),this._expiringNotificationTimeInSeconds=r.expiringNotificationTimeInSeconds}async load(r){const n=this._logger.create("load");if(r.access_token&&r.expires_in!==void 0){const s=r.expires_in;if(n.debug("access token present, remaining duration:",s),s>0){let c=s-this._expiringNotificationTimeInSeconds;c<=0&&(c=1),n.debug("registering expiring timer, raising in",c,"seconds"),this._expiringTimer.init(c)}else n.debug("canceling existing expiring timer because we're past expiration."),this._expiringTimer.cancel();const a=s+1;n.debug("registering expired timer, raising in",a,"seconds"),this._expiredTimer.init(a)}else this._expiringTimer.cancel(),this._expiredTimer.cancel()}async unload(){this._logger.debug("unload: canceling existing access token timers"),this._expiringTimer.cancel(),this._expiredTimer.cancel()}addAccessTokenExpiring(r){return this._expiringTimer.addHandler(r)}removeAccessTokenExpiring(r){this._expiringTimer.removeHandler(r)}addAccessTokenExpired(r){return this._expiredTimer.addHandler(r)}removeAccessTokenExpired(r){this._expiredTimer.removeHandler(r)}},R_=class{constructor(r,n,s,a,c){this._callback=r,this._client_id=n,this._intervalInSeconds=a,this._stopOnError=c,this._logger=new Se("CheckSessionIFrame"),this._timer=null,this._session_state=null,this._message=p=>{p.origin===this._frame_origin&&p.source===this._frame.contentWindow&&(p.data==="error"?(this._logger.error("error message from check session op iframe"),this._stopOnError&&this.stop()):p.data==="changed"?(this._logger.debug("changed message from check session op iframe"),this.stop(),this._callback()):this._logger.debug(p.data+" message from check session op iframe"))};const f=new URL(s);this._frame_origin=f.origin,this._frame=window.document.createElement("iframe"),this._frame.style.visibility="hidden",this._frame.style.position="fixed",this._frame.style.left="-1000px",this._frame.style.top="0",this._frame.width="0",this._frame.height="0",this._frame.src=f.href}load(){return new Promise(r=>{this._frame.onload=()=>{r()},window.document.body.appendChild(this._frame),window.addEventListener("message",this._message,!1)})}start(r){if(this._session_state===r)return;this._logger.create("start"),this.stop(),this._session_state=r;const n=()=>{!this._frame.contentWindow||!this._session_state||this._frame.contentWindow.postMessage(this._client_id+" "+this._session_state,this._frame_origin)};n(),this._timer=setInterval(n,this._intervalInSeconds*1e3)}stop(){this._logger.create("stop"),this._session_state=null,this._timer&&(clearInterval(this._timer),this._timer=null)}},dp=class{constructor(){this._logger=new Se("InMemoryWebStorage"),this._data={}}clear(){this._logger.create("clear"),this._data={}}getItem(r){return this._logger.create(`getItem('${r}')`),this._data[r]}setItem(r,n){this._logger.create(`setItem('${r}')`),this._data[r]=n}removeItem(r){this._logger.create(`removeItem('${r}')`),delete this._data[r]}get length(){return Object.getOwnPropertyNames(this._data).length}key(r){return Object.getOwnPropertyNames(this._data)[r]}},Ru=class extends Error{constructor(r,n){super(n),this.name="ErrorDPoPNonce",this.nonce=r}},qu=class{constructor(r=[],n=null,s={}){this._jwtHandler=n,this._extraHeaders=s,this._logger=new Se("JsonService"),this._contentTypes=[],this._contentTypes.push(...r,"application/json"),n&&this._contentTypes.push("application/jwt")}async fetchWithTimeout(r,n={}){const{timeoutInSeconds:s,...a}=n;if(!s)return await fetch(r,a);const c=new AbortController,f=setTimeout(()=>c.abort(),s*1e3);try{return await fetch(r,{...n,signal:c.signal})}catch(p){throw p instanceof DOMException&&p.name==="AbortError"?new Vu("Network timed out"):p}finally{clearTimeout(f)}}async getJson(r,{token:n,credentials:s,timeoutInSeconds:a}={}){const c=this._logger.create("getJson"),f={Accept:this._contentTypes.join(", ")};n&&(c.debug("token passed, setting Authorization header"),f.Authorization="Bearer "+n),this._appendExtraHeaders(f);let p;try{c.debug("url:",r),p=await this.fetchWithTimeout(r,{method:"GET",headers:f,timeoutInSeconds:a,credentials:s})}catch(x){throw c.error("Network Error"),x}c.debug("HTTP response received, status",p.status);const v=p.headers.get("Content-Type");if(v&&!this._contentTypes.find(x=>v.startsWith(x))&&c.throw(new Error(`Invalid response Content-Type: ${v??"undefined"}, from URL: ${r}`)),p.ok&&this._jwtHandler&&v?.startsWith("application/jwt"))return await this._jwtHandler(await p.text());let y;try{y=await p.json()}catch(x){throw c.error("Error parsing JSON response",x),p.ok?x:new Error(`${p.statusText} (${p.status})`)}if(!p.ok)throw c.error("Error from server:",y),y.error?new vn(y):new Error(`${p.statusText} (${p.status}): ${JSON.stringify(y)}`);return y}async postForm(r,{body:n,basicAuth:s,timeoutInSeconds:a,initCredentials:c,extraHeaders:f}){const p=this._logger.create("postForm"),v={Accept:this._contentTypes.join(", "),"Content-Type":"application/x-www-form-urlencoded",...f};s!==void 0&&(v.Authorization="Basic "+s),this._appendExtraHeaders(v);let y;try{p.debug("url:",r),y=await this.fetchWithTimeout(r,{method:"POST",headers:v,body:n,timeoutInSeconds:a,credentials:c})}catch(j){throw p.error("Network error"),j}p.debug("HTTP response received, status",y.status);const x=y.headers.get("Content-Type");if(x&&!this._contentTypes.find(j=>x.startsWith(j)))throw new Error(`Invalid response Content-Type: ${x??"undefined"}, from URL: ${r}`);const R=await y.text();let N={};if(R)try{N=JSON.parse(R)}catch(j){throw p.error("Error parsing JSON response",j),y.ok?j:new Error(`${y.statusText} (${y.status})`)}if(!y.ok){if(p.error("Error from server:",N),y.headers.has("dpop-nonce")){const j=y.headers.get("dpop-nonce");throw new Ru(j,`${JSON.stringify(N)}`)}throw N.error?new vn(N,n):new Error(`${y.statusText} (${y.status}): ${JSON.stringify(N)}`)}return N}_appendExtraHeaders(r){const n=this._logger.create("appendExtraHeaders"),s=Object.keys(this._extraHeaders),a=["accept","content-type"],c=["authorization"];s.length!==0&&s.forEach(f=>{if(a.includes(f.toLocaleLowerCase())){n.warn("Protected header could not be set",f,a);return}if(c.includes(f.toLocaleLowerCase())&&Object.keys(r).includes(f)){n.warn("Header could not be overridden",f,c);return}const p=typeof this._extraHeaders[f]=="function"?this._extraHeaders[f]():this._extraHeaders[f];p&&p!==""&&(r[f]=p)})}},N_=class{constructor(r){this._settings=r,this._logger=new Se("MetadataService"),this._signingKeys=null,this._metadata=null,this._metadataUrl=this._settings.metadataUrl,this._jsonService=new qu(["application/jwk-set+json"],null,this._settings.extraHeaders),this._settings.signingKeys&&(this._logger.debug("using signingKeys from settings"),this._signingKeys=this._settings.signingKeys),this._settings.metadata&&(this._logger.debug("using metadata from settings"),this._metadata=this._settings.metadata),this._settings.fetchRequestCredentials&&(this._logger.debug("using fetchRequestCredentials from settings"),this._fetchRequestCredentials=this._settings.fetchRequestCredentials)}resetSigningKeys(){this._signingKeys=null}async getMetadata(){const r=this._logger.create("getMetadata");if(this._metadata)return r.debug("using cached values"),this._metadata;if(!this._metadataUrl)throw r.throw(new Error("No authority or metadataUrl configured on settings")),null;r.debug("getting metadata from",this._metadataUrl);const n=await this._jsonService.getJson(this._metadataUrl,{credentials:this._fetchRequestCredentials,timeoutInSeconds:this._settings.requestTimeoutInSeconds});return r.debug("merging remote JSON with seed metadata"),this._metadata=Object.assign({},n,this._settings.metadataSeed),this._metadata}getIssuer(){return this._getMetadataProperty("issuer")}getAuthorizationEndpoint(){return this._getMetadataProperty("authorization_endpoint")}getUserInfoEndpoint(){return this._getMetadataProperty("userinfo_endpoint")}getTokenEndpoint(r=!0){return this._getMetadataProperty("token_endpoint",r)}getCheckSessionIframe(){return this._getMetadataProperty("check_session_iframe",!0)}getEndSessionEndpoint(){return this._getMetadataProperty("end_session_endpoint",!0)}getRevocationEndpoint(r=!0){return this._getMetadataProperty("revocation_endpoint",r)}getKeysEndpoint(r=!0){return this._getMetadataProperty("jwks_uri",r)}async _getMetadataProperty(r,n=!1){const s=this._logger.create(`_getMetadataProperty('${r}')`),a=await this.getMetadata();if(s.debug("resolved"),a[r]===void 0){if(n===!0){s.warn("Metadata does not contain optional property");return}s.throw(new Error("Metadata does not contain property "+r))}return a[r]}async getSigningKeys(){const r=this._logger.create("getSigningKeys");if(this._signingKeys)return r.debug("returning signingKeys from cache"),this._signingKeys;const n=await this.getKeysEndpoint(!1);r.debug("got jwks_uri",n);const s=await this._jsonService.getJson(n,{timeoutInSeconds:this._settings.requestTimeoutInSeconds});if(r.debug("got key set",s),!Array.isArray(s.keys))throw r.throw(new Error("Missing keys on keyset")),null;return this._signingKeys=s.keys,this._signingKeys}},fp=class{constructor({prefix:r="oidc.",store:n=localStorage}={}){this._logger=new Se("WebStorageStateStore"),this._store=n,this._prefix=r}async set(r,n){this._logger.create(`set('${r}')`),r=this._prefix+r,await this._store.setItem(r,n)}async get(r){return this._logger.create(`get('${r}')`),r=this._prefix+r,await this._store.getItem(r)}async remove(r){this._logger.create(`remove('${r}')`),r=this._prefix+r;const n=await this._store.getItem(r);return await this._store.removeItem(r),n}async getAllKeys(){this._logger.create("getAllKeys");const r=await this._store.length,n=[];for(let s=0;s{const a=this._logger.create("_getClaimsFromJwt");try{const c=Ms.decode(s);return a.debug("JWT decoding successful"),c}catch(c){throw a.error("Error parsing JWT response"),c}},this._jsonService=new qu(void 0,this._getClaimsFromJwt,this._settings.extraHeaders)}async getClaims(r){const n=this._logger.create("getClaims");r||this._logger.throw(new Error("No token passed"));const s=await this._metadataService.getUserInfoEndpoint();n.debug("got userinfo url",s);const a=await this._jsonService.getJson(s,{token:r,credentials:this._settings.fetchRequestCredentials,timeoutInSeconds:this._settings.requestTimeoutInSeconds});return n.debug("got claims",a),a}},hp=class{constructor(r,n){this._settings=r,this._metadataService=n,this._logger=new Se("TokenClient"),this._jsonService=new qu(this._settings.revokeTokenAdditionalContentTypes,null,this._settings.extraHeaders)}async exchangeCode({grant_type:r="authorization_code",redirect_uri:n=this._settings.redirect_uri,client_id:s=this._settings.client_id,client_secret:a=this._settings.client_secret,extraHeaders:c,...f}){const p=this._logger.create("exchangeCode");s||p.throw(new Error("A client_id is required")),n||p.throw(new Error("A redirect_uri is required")),f.code||p.throw(new Error("A code is required"));const v=new URLSearchParams({grant_type:r,redirect_uri:n});for(const[N,j]of Object.entries(f))j!=null&&v.set(N,j);if((this._settings.client_authentication==="client_secret_basic"||this._settings.client_authentication==="client_secret_jwt")&&a==null)throw p.throw(new Error("A client_secret is required")),null;let y;const x=await this._metadataService.getTokenEndpoint(!1);switch(this._settings.client_authentication){case"client_secret_basic":y=Je.generateBasicAuth(s,a);break;case"client_secret_post":v.append("client_id",s),a&&v.append("client_secret",a);break;case"client_secret_jwt":{const N=await Je.generateClientAssertionJwt(s,a,x,this._settings.token_endpoint_auth_signing_alg);v.append("client_id",s),v.append("client_assertion_type","urn:ietf:params:oauth:client-assertion-type:jwt-bearer"),v.append("client_assertion",N);break}}p.debug("got token endpoint");const R=await this._jsonService.postForm(x,{body:v,basicAuth:y,timeoutInSeconds:this._settings.requestTimeoutInSeconds,initCredentials:this._settings.fetchRequestCredentials,extraHeaders:c});return p.debug("got response"),R}async exchangeCredentials({grant_type:r="password",client_id:n=this._settings.client_id,client_secret:s=this._settings.client_secret,scope:a=this._settings.scope,...c}){const f=this._logger.create("exchangeCredentials");n||f.throw(new Error("A client_id is required"));const p=new URLSearchParams({grant_type:r});this._settings.omitScopeWhenRequesting||p.set("scope",a);for(const[R,N]of Object.entries(c))N!=null&&p.set(R,N);if((this._settings.client_authentication==="client_secret_basic"||this._settings.client_authentication==="client_secret_jwt")&&s==null)throw f.throw(new Error("A client_secret is required")),null;let v;const y=await this._metadataService.getTokenEndpoint(!1);switch(this._settings.client_authentication){case"client_secret_basic":v=Je.generateBasicAuth(n,s);break;case"client_secret_post":p.append("client_id",n),s&&p.append("client_secret",s);break;case"client_secret_jwt":{const R=await Je.generateClientAssertionJwt(n,s,y,this._settings.token_endpoint_auth_signing_alg);p.append("client_id",n),p.append("client_assertion_type","urn:ietf:params:oauth:client-assertion-type:jwt-bearer"),p.append("client_assertion",R);break}}f.debug("got token endpoint");const x=await this._jsonService.postForm(y,{body:p,basicAuth:v,timeoutInSeconds:this._settings.requestTimeoutInSeconds,initCredentials:this._settings.fetchRequestCredentials});return f.debug("got response"),x}async exchangeRefreshToken({grant_type:r="refresh_token",client_id:n=this._settings.client_id,client_secret:s=this._settings.client_secret,timeoutInSeconds:a,extraHeaders:c,...f}){const p=this._logger.create("exchangeRefreshToken");n||p.throw(new Error("A client_id is required")),f.refresh_token||p.throw(new Error("A refresh_token is required"));const v=new URLSearchParams({grant_type:r});for(const[N,j]of Object.entries(f))Array.isArray(j)?j.forEach(O=>v.append(N,O)):j!=null&&v.set(N,j);if((this._settings.client_authentication==="client_secret_basic"||this._settings.client_authentication==="client_secret_jwt")&&s==null)throw p.throw(new Error("A client_secret is required")),null;let y;const x=await this._metadataService.getTokenEndpoint(!1);switch(this._settings.client_authentication){case"client_secret_basic":y=Je.generateBasicAuth(n,s);break;case"client_secret_post":v.append("client_id",n),s&&v.append("client_secret",s);break;case"client_secret_jwt":{const N=await Je.generateClientAssertionJwt(n,s,x,this._settings.token_endpoint_auth_signing_alg);v.append("client_id",n),v.append("client_assertion_type","urn:ietf:params:oauth:client-assertion-type:jwt-bearer"),v.append("client_assertion",N);break}}p.debug("got token endpoint");const R=await this._jsonService.postForm(x,{body:v,basicAuth:y,timeoutInSeconds:a,initCredentials:this._settings.fetchRequestCredentials,extraHeaders:c});return p.debug("got response"),R}async revoke(r){var n;const s=this._logger.create("revoke");r.token||s.throw(new Error("A token is required"));const a=await this._metadataService.getRevocationEndpoint(!1);s.debug(`got revocation endpoint, revoking ${(n=r.token_type_hint)!=null?n:"default token type"}`);const c=new URLSearchParams;for(const[f,p]of Object.entries(r))p!=null&&c.set(f,p);c.set("client_id",this._settings.client_id),this._settings.client_secret&&c.set("client_secret",this._settings.client_secret),await this._jsonService.postForm(a,{body:c,timeoutInSeconds:this._settings.requestTimeoutInSeconds}),s.debug("got response")}},O_=class{constructor(r,n,s){this._settings=r,this._metadataService=n,this._claimsService=s,this._logger=new Se("ResponseValidator"),this._userInfoService=new j_(this._settings,this._metadataService),this._tokenClient=new hp(this._settings,this._metadataService)}async validateSigninResponse(r,n,s){const a=this._logger.create("validateSigninResponse");this._processSigninState(r,n),a.debug("state processed"),await this._processCode(r,n,s),a.debug("code processed"),r.isOpenId&&this._validateIdTokenAttributes(r,"",n.nonce),a.debug("tokens validated"),await this._processClaims(r,n?.skipUserInfo,r.isOpenId),a.debug("claims processed")}async validateCredentialsResponse(r,n){const s=this._logger.create("validateCredentialsResponse"),a=r.isOpenId&&!!r.id_token;a&&this._validateIdTokenAttributes(r),s.debug("tokens validated"),await this._processClaims(r,n,a),s.debug("claims processed")}async validateRefreshResponse(r,n){var s,a;const c=this._logger.create("validateRefreshResponse");r.userState=n.data,(s=r.session_state)!=null||(r.session_state=n.session_state),(a=r.scope)!=null||(r.scope=n.scope),r.isOpenId&&r.id_token&&(this._validateIdTokenAttributes(r,n.id_token),c.debug("ID Token validated")),r.id_token||(r.id_token=n.id_token,r.profile=n.profile);const f=r.isOpenId&&!!r.id_token;await this._processClaims(r,!1,f),c.debug("claims processed")}validateSignoutResponse(r,n){const s=this._logger.create("validateSignoutResponse");if(n.id!==r.state&&s.throw(new Error("State does not match")),s.debug("state validated"),r.userState=n.data,r.error)throw s.warn("Response was error",r.error),new vn(r)}_processSigninState(r,n){var s;const a=this._logger.create("_processSigninState");if(n.id!==r.state&&a.throw(new Error("State does not match")),n.client_id||a.throw(new Error("No client_id on state")),n.authority||a.throw(new Error("No authority on state")),this._settings.authority!==n.authority&&a.throw(new Error("authority mismatch on settings vs. signin state")),this._settings.client_id&&this._settings.client_id!==n.client_id&&a.throw(new Error("client_id mismatch on settings vs. signin state")),a.debug("state validated"),r.userState=n.data,r.url_state=n.url_state,(s=r.scope)!=null||(r.scope=n.scope),r.error)throw a.warn("Response was error",r.error),new vn(r);n.code_verifier&&!r.code&&a.throw(new Error("Expected code in response"))}async _processClaims(r,n=!1,s=!0){const a=this._logger.create("_processClaims");if(r.profile=this._claimsService.filterProtocolClaims(r.profile),n||!this._settings.loadUserInfo||!r.access_token){a.debug("not loading user info");return}a.debug("loading user info");const c=await this._userInfoService.getClaims(r.access_token);a.debug("user info claims received from user info endpoint"),s&&c.sub!==r.profile.sub&&a.throw(new Error("subject from UserInfo response does not match subject in ID Token")),r.profile=this._claimsService.mergeClaims(r.profile,this._claimsService.filterProtocolClaims(c)),a.debug("user info claims received, updated profile:",r.profile)}async _processCode(r,n,s){const a=this._logger.create("_processCode");if(r.code){a.debug("Validating code");const c=await this._tokenClient.exchangeCode({client_id:n.client_id,client_secret:n.client_secret,code:r.code,redirect_uri:n.redirect_uri,code_verifier:n.code_verifier,extraHeaders:s,...n.extraTokenParams});Object.assign(r,c)}else a.debug("No code to process")}_validateIdTokenAttributes(r,n,s){var a;const c=this._logger.create("_validateIdTokenAttributes");c.debug("decoding ID Token JWT");const f=Ms.decode((a=r.id_token)!=null?a:"");if(f.sub||c.throw(new Error("ID Token is missing a subject claim")),s&&f.nonce!==s&&c.throw(new Error("nonce in id_token does not match nonce in client storage")),n){const p=Ms.decode(n);f.sub!==p.sub&&c.throw(new Error("sub in id_token does not match current sub")),f.auth_time&&f.auth_time!==p.auth_time&&c.throw(new Error("auth_time in id_token does not match original auth_time")),f.azp&&f.azp!==p.azp&&c.throw(new Error("azp in id_token does not match original azp")),!f.azp&&p.azp&&c.throw(new Error("azp not in id_token, but present in original id_token"))}r.profile=f}},pa=class Pu{constructor(n){this.id=n.id||Je.generateUUIDv4(),this.data=n.data,n.created&&n.created>0?this.created=n.created:this.created=gr.getEpochTime(),this.request_type=n.request_type,this.url_state=n.url_state}toStorageString(){return new Se("State").create("toStorageString"),JSON.stringify({id:this.id,data:this.data,created:this.created,request_type:this.request_type,url_state:this.url_state})}static fromStorageString(n){return Se.createStatic("State","fromStorageString"),Promise.resolve(new Pu(JSON.parse(n)))}static async clearStaleState(n,s){const a=Se.createStatic("State","clearStaleState"),c=gr.getEpochTime()-s,f=await n.getAllKeys();a.debug("got keys",f);for(let p=0;pY.searchParams.append("resource",ue));for(const[me,ue]of Object.entries({response_mode:y,...L,...Q}))ue!=null&&Y.searchParams.append(me,ue.toString());return new mp({url:Y.href,state:J})}};gp._logger=new Se("SigninRequest");var D_=gp,z_="openid",uu=class{constructor(r){if(this.access_token="",this.token_type="",this.profile={},this.state=r.get("state"),this.session_state=r.get("session_state"),this.state){const n=decodeURIComponent(this.state).split(Ti);this.state=n[0],n.length>1&&(this.url_state=n.slice(1).join(Ti))}this.error=r.get("error"),this.error_description=r.get("error_description"),this.error_uri=r.get("error_uri"),this.code=r.get("code")}get expires_in(){if(this.expires_at!==void 0)return this.expires_at-gr.getEpochTime()}set expires_in(r){typeof r=="string"&&(r=Number(r)),r!==void 0&&r>=0&&(this.expires_at=Math.floor(r)+gr.getEpochTime())}get isOpenId(){var r;return((r=this.scope)==null?void 0:r.split(" ").includes(z_))||!!this.id_token}},F_=class{constructor({url:r,state_data:n,id_token_hint:s,post_logout_redirect_uri:a,extraQueryParams:c,request_type:f,client_id:p,url_state:v}){if(this._logger=new Se("SignoutRequest"),!r)throw this._logger.error("ctor: No url passed"),new Error("url");const y=new URL(r);if(s&&y.searchParams.append("id_token_hint",s),p&&y.searchParams.append("client_id",p),a&&(y.searchParams.append("post_logout_redirect_uri",a),n||v)){this.state=new pa({data:n,request_type:f,url_state:v});let x=this.state.id;v&&(x=`${x}${Ti}${v}`),y.searchParams.append("state",x)}for(const[x,R]of Object.entries({...c}))R!=null&&y.searchParams.append(x,R.toString());this.url=y.href}},$_=class{constructor(r){if(this.state=r.get("state"),this.state){const n=decodeURIComponent(this.state).split(Ti);this.state=n[0],n.length>1&&(this.url_state=n.slice(1).join(Ti))}this.error=r.get("error"),this.error_description=r.get("error_description"),this.error_uri=r.get("error_uri")}},L_=["nbf","jti","auth_time","nonce","acr","amr","azp","at_hash"],V_=["sub","iss","aud","exp","iat"],q_=class{constructor(r){this._settings=r,this._logger=new Se("ClaimsService")}filterProtocolClaims(r){const n={...r};if(this._settings.filterProtocolClaims){let s;Array.isArray(this._settings.filterProtocolClaims)?s=this._settings.filterProtocolClaims:s=L_;for(const a of s)V_.includes(a)||delete n[a]}return n}mergeClaims(r,n){const s={...r};for(const[a,c]of Object.entries(n))if(s[a]!==c)if(Array.isArray(s[a])||Array.isArray(c))if(this._settings.mergeClaimsStrategy.array=="replace")s[a]=c;else{const f=Array.isArray(s[a])?s[a]:[s[a]];for(const p of Array.isArray(c)?c:[c])f.includes(p)||f.push(p);s[a]=f}else typeof s[a]=="object"&&typeof c=="object"?s[a]=this.mergeClaims(s[a],c):s[a]=c;return s}},yp=class{constructor(r,n){this.keys=r,this.nonce=n}},H_=class{constructor(r,n){this._logger=new Se("OidcClient"),this.settings=r instanceof Nu?r:new Nu(r),this.metadataService=n??new N_(this.settings),this._claimsService=new q_(this.settings),this._validator=new O_(this.settings,this.metadataService,this._claimsService),this._tokenClient=new hp(this.settings,this.metadataService)}async createSigninRequest({state:r,request:n,request_uri:s,request_type:a,id_token_hint:c,login_hint:f,skipUserInfo:p,nonce:v,url_state:y,response_type:x=this.settings.response_type,scope:R=this.settings.scope,redirect_uri:N=this.settings.redirect_uri,prompt:j=this.settings.prompt,display:O=this.settings.display,max_age:q=this.settings.max_age,ui_locales:Q=this.settings.ui_locales,acr_values:$=this.settings.acr_values,resource:fe=this.settings.resource,response_mode:T=this.settings.response_mode,extraQueryParams:A=this.settings.extraQueryParams,extraTokenParams:L=this.settings.extraTokenParams,dpopJkt:J,omitScopeWhenRequesting:Y=this.settings.omitScopeWhenRequesting}){const ge=this._logger.create("createSigninRequest");if(x!=="code")throw new Error("Only the Authorization Code flow (with PKCE) is supported");const me=await this.metadataService.getAuthorizationEndpoint();ge.debug("Received authorization endpoint",me);const ue=await D_.create({url:me,authority:this.settings.authority,client_id:this.settings.client_id,redirect_uri:N,response_type:x,scope:R,state_data:r,url_state:y,prompt:j,display:O,max_age:q,ui_locales:Q,id_token_hint:c,login_hint:f,acr_values:$,dpopJkt:J,resource:fe,request:n,request_uri:s,extraQueryParams:A,extraTokenParams:L,request_type:a,response_mode:T,client_secret:this.settings.client_secret,skipUserInfo:p,nonce:v,disablePKCE:this.settings.disablePKCE,omitScopeWhenRequesting:Y});await this.clearStaleState();const Re=ue.state;return await this.settings.stateStore.set(Re.id,Re.toStorageString()),ue}async readSigninResponseState(r,n=!1){const s=this._logger.create("readSigninResponseState"),a=new uu(Uu.readParams(r,this.settings.response_mode));if(!a.state)throw s.throw(new Error("No state in response")),null;const c=await this.settings.stateStore[n?"remove":"get"](a.state);if(!c)throw s.throw(new Error("No matching state found in storage")),null;return{state:await pp.fromStorageString(c),response:a}}async processSigninResponse(r,n,s=!0){const a=this._logger.create("processSigninResponse"),{state:c,response:f}=await this.readSigninResponseState(r,s);if(a.debug("received state from storage; validating response"),this.settings.dpop&&this.settings.dpop.store){const p=await this.getDpopProof(this.settings.dpop.store);n={...n,DPoP:p}}try{await this._validator.validateSigninResponse(f,c,n)}catch(p){if(p instanceof Ru&&this.settings.dpop){const v=await this.getDpopProof(this.settings.dpop.store,p.nonce);n.DPoP=v,await this._validator.validateSigninResponse(f,c,n)}else throw p}return f}async getDpopProof(r,n){let s,a;return(await r.getAllKeys()).includes(this.settings.client_id)?(a=await r.get(this.settings.client_id),a.nonce!==n&&n&&(a.nonce=n,await r.set(this.settings.client_id,a))):(s=await Je.generateDPoPKeys(),a=new yp(s,n),await r.set(this.settings.client_id,a)),await Je.generateDPoPProof({url:await this.metadataService.getTokenEndpoint(!1),httpMethod:"POST",keyPair:a.keys,nonce:a.nonce})}async processResourceOwnerPasswordCredentials({username:r,password:n,skipUserInfo:s=!1,extraTokenParams:a={}}){const c=await this._tokenClient.exchangeCredentials({username:r,password:n,...a}),f=new uu(new URLSearchParams);return Object.assign(f,c),await this._validator.validateCredentialsResponse(f,s),f}async useRefreshToken({state:r,redirect_uri:n,resource:s,timeoutInSeconds:a,extraHeaders:c,extraTokenParams:f}){var p;const v=this._logger.create("useRefreshToken");let y;if(this.settings.refreshTokenAllowedScope===void 0)y=r.scope;else{const N=this.settings.refreshTokenAllowedScope.split(" ");y=(((p=r.scope)==null?void 0:p.split(" "))||[]).filter(O=>N.includes(O)).join(" ")}if(this.settings.dpop&&this.settings.dpop.store){const N=await this.getDpopProof(this.settings.dpop.store);c={...c,DPoP:N}}let x;try{x=await this._tokenClient.exchangeRefreshToken({refresh_token:r.refresh_token,scope:y,redirect_uri:n,resource:s,timeoutInSeconds:a,extraHeaders:c,...f})}catch(N){if(N instanceof Ru&&this.settings.dpop)c.DPoP=await this.getDpopProof(this.settings.dpop.store,N.nonce),x=await this._tokenClient.exchangeRefreshToken({refresh_token:r.refresh_token,scope:y,redirect_uri:n,resource:s,timeoutInSeconds:a,extraHeaders:c,...f});else throw N}const R=new uu(new URLSearchParams);return Object.assign(R,x),v.debug("validating response",R),await this._validator.validateRefreshResponse(R,{...r,scope:y}),R}async createSignoutRequest({state:r,id_token_hint:n,client_id:s,request_type:a,url_state:c,post_logout_redirect_uri:f=this.settings.post_logout_redirect_uri,extraQueryParams:p=this.settings.extraQueryParams}={}){const v=this._logger.create("createSignoutRequest"),y=await this.metadataService.getEndSessionEndpoint();if(!y)throw v.throw(new Error("No end session endpoint")),null;v.debug("Received end session endpoint",y),!s&&f&&!n&&(s=this.settings.client_id);const x=new F_({url:y,id_token_hint:n,client_id:s,post_logout_redirect_uri:f,state_data:r,extraQueryParams:p,request_type:a,url_state:c});await this.clearStaleState();const R=x.state;return R&&(v.debug("Signout request has state to persist"),await this.settings.stateStore.set(R.id,R.toStorageString())),x}async readSignoutResponseState(r,n=!1){const s=this._logger.create("readSignoutResponseState"),a=new $_(Uu.readParams(r,this.settings.response_mode));if(!a.state){if(s.debug("No state in response"),a.error)throw s.warn("Response was error:",a.error),new vn(a);return{state:void 0,response:a}}const c=await this.settings.stateStore[n?"remove":"get"](a.state);if(!c)throw s.throw(new Error("No matching state found in storage")),null;return{state:await pa.fromStorageString(c),response:a}}async processSignoutResponse(r){const n=this._logger.create("processSignoutResponse"),{state:s,response:a}=await this.readSignoutResponseState(r,!0);return s?(n.debug("Received state from storage; validating response"),this._validator.validateSignoutResponse(a,s)):n.debug("No state from storage; skipping response validation"),a}clearStaleState(){return this._logger.create("clearStaleState"),pa.clearStaleState(this.settings.stateStore,this.settings.staleStateAgeInSeconds)}async revokeToken(r,n){return this._logger.create("revokeToken"),await this._tokenClient.revoke({token:r,token_type_hint:n})}},K_=class{constructor(r){this._userManager=r,this._logger=new Se("SessionMonitor"),this._start=async n=>{const s=n.session_state;if(!s)return;const a=this._logger.create("_start");if(n.profile?(this._sub=n.profile.sub,a.debug("session_state",s,", sub",this._sub)):(this._sub=void 0,a.debug("session_state",s,", anonymous user")),this._checkSessionIFrame){this._checkSessionIFrame.start(s);return}try{const c=await this._userManager.metadataService.getCheckSessionIframe();if(c){a.debug("initializing check session iframe");const f=this._userManager.settings.client_id,p=this._userManager.settings.checkSessionIntervalInSeconds,v=this._userManager.settings.stopCheckSessionOnError,y=new R_(this._callback,f,c,p,v);await y.load(),this._checkSessionIFrame=y,y.start(s)}else a.warn("no check session iframe found in the metadata")}catch(c){a.error("Error from getCheckSessionIframe:",c instanceof Error?c.message:c)}},this._stop=()=>{const n=this._logger.create("_stop");if(this._sub=void 0,this._checkSessionIFrame&&this._checkSessionIFrame.stop(),this._userManager.settings.monitorAnonymousSession){const s=setInterval(async()=>{clearInterval(s);try{const a=await this._userManager.querySessionStatus();if(a){const c={session_state:a.session_state,profile:a.sub?{sub:a.sub}:null};this._start(c)}}catch(a){n.error("error from querySessionStatus",a instanceof Error?a.message:a)}},1e3)}},this._callback=async()=>{const n=this._logger.create("_callback");try{const s=await this._userManager.querySessionStatus();let a=!0;s&&this._checkSessionIFrame?s.sub===this._sub?(a=!1,this._checkSessionIFrame.start(s.session_state),n.debug("same sub still logged in at OP, session state has changed, restarting check session iframe; session_state",s.session_state),await this._userManager.events._raiseUserSessionChanged()):n.debug("different subject signed into OP",s.sub):n.debug("subject no longer signed into OP"),a?this._sub?await this._userManager.events._raiseUserSignedOut():await this._userManager.events._raiseUserSignedIn():n.debug("no change in session detected, no event to raise")}catch(s){this._sub&&(n.debug("Error calling queryCurrentSigninSession; raising signed out event",s),await this._userManager.events._raiseUserSignedOut())}},r||this._logger.throw(new Error("No user manager passed")),this._userManager.events.addUserLoaded(this._start),this._userManager.events.addUserUnloaded(this._stop),this._init().catch(n=>{this._logger.error(n)})}async _init(){this._logger.create("_init");const r=await this._userManager.getUser();if(r)this._start(r);else if(this._userManager.settings.monitorAnonymousSession){const n=await this._userManager.querySessionStatus();if(n){const s={session_state:n.session_state,profile:n.sub?{sub:n.sub}:null};this._start(s)}}}},cu=class wp{constructor(n){var s;this.id_token=n.id_token,this.session_state=(s=n.session_state)!=null?s:null,this.access_token=n.access_token,this.refresh_token=n.refresh_token,this.token_type=n.token_type,this.scope=n.scope,this.profile=n.profile,this.expires_at=n.expires_at,this.state=n.userState,this.url_state=n.url_state}get expires_in(){if(this.expires_at!==void 0)return this.expires_at-gr.getEpochTime()}set expires_in(n){n!==void 0&&(this.expires_at=Math.floor(n)+gr.getEpochTime())}get expired(){const n=this.expires_in;if(n!==void 0)return n<=0}get scopes(){var n,s;return(s=(n=this.scope)==null?void 0:n.split(" "))!=null?s:[]}toStorageString(){return new Se("User").create("toStorageString"),JSON.stringify({id_token:this.id_token,session_state:this.session_state,access_token:this.access_token,refresh_token:this.refresh_token,token_type:this.token_type,scope:this.scope,profile:this.profile,expires_at:this.expires_at})}static fromStorageString(n){return Se.createStatic("User","fromStorageString"),new wp(JSON.parse(n))}},fh="oidc-client",vp=class{constructor(){this._abort=new Or("Window navigation aborted"),this._disposeHandlers=new Set,this._window=null}async navigate(r){const n=this._logger.create("navigate");if(!this._window)throw new Error("Attempted to navigate on a disposed window");n.debug("setting URL in window"),this._window.location.replace(r.url);const{url:s,keepOpen:a}=await new Promise((c,f)=>{const p=y=>{var x;const R=y.data,N=(x=r.scriptOrigin)!=null?x:window.location.origin;if(!(y.origin!==N||R?.source!==fh)){try{const j=Uu.readParams(R.url,r.response_mode).get("state");if(j||n.warn("no state found in response url"),y.source!==this._window&&j!==r.state)return}catch{this._dispose(),f(new Error("Invalid response from window"))}c(R)}};window.addEventListener("message",p,!1),this._disposeHandlers.add(()=>window.removeEventListener("message",p,!1));const v=new BroadcastChannel(`oidc-client-popup-${r.state}`);v.addEventListener("message",p,!1),this._disposeHandlers.add(()=>v.close()),this._disposeHandlers.add(this._abort.addHandler(y=>{this._dispose(),f(y)}))});return n.debug("got response from window"),this._dispose(),a||this.close(),{url:s}}_dispose(){this._logger.create("_dispose");for(const r of this._disposeHandlers)r();this._disposeHandlers.clear()}static _notifyParent(r,n,s=!1,a=window.location.origin){const c={source:fh,url:n,keepOpen:s},f=new Se("_notifyParent");if(r)f.debug("With parent. Using parent.postMessage."),r.postMessage(c,a);else{f.debug("No parent. Using BroadcastChannel.");const p=new URL(n).searchParams.get("state");if(!p)throw new Error("No parent and no state in URL. Can't complete notification.");const v=new BroadcastChannel(`oidc-client-popup-${p}`);v.postMessage(c),v.close()}}},_p={location:!1,toolbar:!1,height:640,closePopupWindowAfterInSeconds:-1},Sp="_blank",W_=60,Q_=2,xp=10,J_=class extends Nu{constructor(r){const{popup_redirect_uri:n=r.redirect_uri,popup_post_logout_redirect_uri:s=r.post_logout_redirect_uri,popupWindowFeatures:a=_p,popupWindowTarget:c=Sp,redirectMethod:f="assign",redirectTarget:p="self",iframeNotifyParentOrigin:v=r.iframeNotifyParentOrigin,iframeScriptOrigin:y=r.iframeScriptOrigin,requestTimeoutInSeconds:x,silent_redirect_uri:R=r.redirect_uri,silentRequestTimeoutInSeconds:N,automaticSilentRenew:j=!0,validateSubOnSilentRenew:O=!0,includeIdTokenInSilentRenew:q=!1,monitorSession:Q=!1,monitorAnonymousSession:$=!1,checkSessionIntervalInSeconds:fe=Q_,query_status_response_type:T="code",stopCheckSessionOnError:A=!0,revokeTokenTypes:L=["access_token","refresh_token"],revokeTokensOnSignout:J=!1,includeIdTokenInSilentSignout:Y=!1,accessTokenExpiringNotificationTimeInSeconds:ge=W_,maxSilentRenewTimeoutRetries:me,userStore:ue}=r;if(super(r),this.popup_redirect_uri=n,this.popup_post_logout_redirect_uri=s,this.popupWindowFeatures=a,this.popupWindowTarget=c,this.redirectMethod=f,this.redirectTarget=p,this.iframeNotifyParentOrigin=v,this.iframeScriptOrigin=y,this.silent_redirect_uri=R,this.silentRequestTimeoutInSeconds=N||x||xp,this.automaticSilentRenew=j,this.validateSubOnSilentRenew=O,this.includeIdTokenInSilentRenew=q,this.monitorSession=Q,this.monitorAnonymousSession=$,this.checkSessionIntervalInSeconds=fe,this.stopCheckSessionOnError=A,this.query_status_response_type=T,this.revokeTokenTypes=L,this.revokeTokensOnSignout=J,this.includeIdTokenInSilentSignout=Y,this.accessTokenExpiringNotificationTimeInSeconds=ge,this.maxSilentRenewTimeoutRetries=me,ue)this.userStore=ue;else{const Re=typeof window<"u"?window.sessionStorage:new dp;this.userStore=new fp({store:Re})}}},hh=class Ip extends vp{constructor({silentRequestTimeoutInSeconds:n=xp}){super(),this._logger=new Se("IFrameWindow"),this._timeoutInSeconds=n,this._frame=Ip.createHiddenIframe(),this._window=this._frame.contentWindow}static createHiddenIframe(){const n=window.document.createElement("iframe");return n.style.visibility="hidden",n.style.position="fixed",n.style.left="-1000px",n.style.top="0",n.width="0",n.height="0",window.document.body.appendChild(n),n}async navigate(n){this._logger.debug("navigate: Using timeout of:",this._timeoutInSeconds);const s=setTimeout(()=>{this._abort.raise(new Vu("IFrame timed out without a response"))},this._timeoutInSeconds*1e3);return this._disposeHandlers.add(()=>clearTimeout(s)),await super.navigate(n)}close(){var n;this._frame&&(this._frame.parentNode&&(this._frame.addEventListener("load",s=>{var a;const c=s.target;(a=c.parentNode)==null||a.removeChild(c),this._abort.raise(new Error("IFrame removed from DOM"))},!0),(n=this._frame.contentWindow)==null||n.location.replace("about:blank")),this._frame=null),this._window=null}static notifyParent(n,s){return super._notifyParent(window.parent,n,!1,s)}},G_=class{constructor(r){this._settings=r,this._logger=new Se("IFrameNavigator")}async prepare({silentRequestTimeoutInSeconds:r=this._settings.silentRequestTimeoutInSeconds}){return new hh({silentRequestTimeoutInSeconds:r})}async callback(r){this._logger.create("callback"),hh.notifyParent(r,this._settings.iframeNotifyParentOrigin)}},X_=500,Y_=1e3,ph=class extends vp{constructor({popupWindowTarget:r=Sp,popupWindowFeatures:n={},popupSignal:s,popupAbortOnClose:a}){super(),this._logger=new Se("PopupWindow");const c=dh.center({..._p,...n});this._window=window.open(void 0,r,dh.serialize(c)),this.abortOnClose=!!a,s&&s.addEventListener("abort",()=>{var f;this._abort.raise(new Error((f=s.reason)!=null?f:"Popup aborted"))}),n.closePopupWindowAfterInSeconds&&n.closePopupWindowAfterInSeconds>0&&setTimeout(()=>{if(!this._window||typeof this._window.closed!="boolean"||this._window.closed){this._abort.raise(new Error("Popup blocked by user"));return}this.close()},n.closePopupWindowAfterInSeconds*Y_)}async navigate(r){var n;(n=this._window)==null||n.focus();const s=setInterval(()=>{(!this._window||this._window.closed)&&(this._logger.debug("Popup closed by user or isolated by redirect"),a(),this._disposeHandlers.delete(a),this.abortOnClose&&this._abort.raise(new Error("Popup closed by user")))},X_),a=()=>clearInterval(s);return this._disposeHandlers.add(a),await super.navigate(r)}close(){this._window&&(this._window.closed||(this._window.close(),this._abort.raise(new Error("Popup closed")))),this._window=null}static notifyOpener(r,n){super._notifyParent(window.opener,r,n),!n&&!window.opener&&window.close()}},Z_=class{constructor(r){this._settings=r,this._logger=new Se("PopupNavigator")}async prepare({popupWindowFeatures:r=this._settings.popupWindowFeatures,popupWindowTarget:n=this._settings.popupWindowTarget,popupSignal:s,popupAbortOnClose:a}){return new ph({popupWindowFeatures:r,popupWindowTarget:n,popupSignal:s,popupAbortOnClose:a})}async callback(r,{keepOpen:n=!1}){this._logger.create("callback"),ph.notifyOpener(r,n)}},eS=class{constructor(r){this._settings=r,this._logger=new Se("RedirectNavigator")}async prepare({redirectMethod:r=this._settings.redirectMethod,redirectTarget:n=this._settings.redirectTarget}){var s;this._logger.create("prepare");let a=window.self;n==="top"&&(a=(s=window.top)!=null?s:window.self);const c=a.location[r].bind(a.location);let f;return{navigate:async p=>(this._logger.create("navigate"),await new Promise((y,x)=>{f=x,window.addEventListener("pageshow",()=>y(window.location.href)),c(p.url)})),close:()=>{this._logger.create("close"),f?.(new Error("Redirect aborted")),a.stop()}}}async callback(){}},tS=class extends U_{constructor(r){super({expiringNotificationTimeInSeconds:r.accessTokenExpiringNotificationTimeInSeconds}),this._logger=new Se("UserManagerEvents"),this._userLoaded=new Or("User loaded"),this._userUnloaded=new Or("User unloaded"),this._silentRenewError=new Or("Silent renew error"),this._userSignedIn=new Or("User signed in"),this._userSignedOut=new Or("User signed out"),this._userSessionChanged=new Or("User session changed")}async load(r,n=!0){await super.load(r),n&&await this._userLoaded.raise(r)}async unload(){await super.unload(),await this._userUnloaded.raise()}addUserLoaded(r){return this._userLoaded.addHandler(r)}removeUserLoaded(r){return this._userLoaded.removeHandler(r)}addUserUnloaded(r){return this._userUnloaded.addHandler(r)}removeUserUnloaded(r){return this._userUnloaded.removeHandler(r)}addSilentRenewError(r){return this._silentRenewError.addHandler(r)}removeSilentRenewError(r){return this._silentRenewError.removeHandler(r)}async _raiseSilentRenewError(r){await this._silentRenewError.raise(r)}addUserSignedIn(r){return this._userSignedIn.addHandler(r)}removeUserSignedIn(r){this._userSignedIn.removeHandler(r)}async _raiseUserSignedIn(){await this._userSignedIn.raise()}addUserSignedOut(r){return this._userSignedOut.addHandler(r)}removeUserSignedOut(r){this._userSignedOut.removeHandler(r)}async _raiseUserSignedOut(){await this._userSignedOut.raise()}addUserSessionChanged(r){return this._userSessionChanged.addHandler(r)}removeUserSessionChanged(r){this._userSessionChanged.removeHandler(r)}async _raiseUserSessionChanged(){await this._userSessionChanged.raise()}},rS=class{constructor(r){this._userManager=r,this._logger=new Se("SilentRenewService"),this._isStarted=!1,this._retryTimer=new gr("Retry Silent Renew"),this._timeoutRetryCount=0,this._tokenExpiring=async()=>{const n=this._logger.create("_tokenExpiring");try{await this._userManager.signinSilent(),this._timeoutRetryCount=0,n.debug("silent token renewal successful")}catch(s){if(s instanceof Vu){this._timeoutRetryCount++;const a=this._userManager.settings.maxSilentRenewTimeoutRetries;if(a!==void 0&&this._timeoutRetryCount>a){n.error(`Timeout retry limit reached (${this._timeoutRetryCount} > ${a}), raising silentRenewError:`,s),this._timeoutRetryCount=0,await this._userManager.events._raiseSilentRenewError(s);return}n.warn(`ErrorTimeout from signinSilent (attempt ${this._timeoutRetryCount}), retry in 5s:`,s),this._retryTimer.init(5);return}n.error("Error from signinSilent:",s),this._timeoutRetryCount=0,await this._userManager.events._raiseSilentRenewError(s)}}}async start(){const r=this._logger.create("start");if(!this._isStarted){this._isStarted=!0,this._userManager.events.addAccessTokenExpiring(this._tokenExpiring),this._retryTimer.addHandler(this._tokenExpiring);try{await this._userManager.getUser()}catch(n){r.error("getUser error",n)}}}stop(){this._isStarted&&(this._retryTimer.cancel(),this._retryTimer.removeHandler(this._tokenExpiring),this._userManager.events.removeAccessTokenExpiring(this._tokenExpiring),this._isStarted=!1)}},nS=class{constructor(r){this.refresh_token=r.refresh_token,this.id_token=r.id_token,this.session_state=r.session_state,this.scope=r.scope,this.profile=r.profile,this.data=r.state}},iS=class{constructor(r,n,s,a){this._logger=new Se("UserManager"),this.settings=new J_(r),this._client=new H_(r),this._redirectNavigator=n??new eS(this.settings),this._popupNavigator=s??new Z_(this.settings),this._iframeNavigator=a??new G_(this.settings),this._events=new tS(this.settings),this._silentRenewService=new rS(this),this.settings.automaticSilentRenew&&this.startSilentRenew(),this._sessionMonitor=null,this.settings.monitorSession&&(this._sessionMonitor=new K_(this))}get events(){return this._events}get metadataService(){return this._client.metadataService}async getUser(r=!1){const n=this._logger.create("getUser"),s=await this._loadUser();return s?(n.info("user loaded"),await this._events.load(s,r),s):(n.info("user not found in storage"),null)}async removeUser(){const r=this._logger.create("removeUser");await this.storeUser(null),r.info("user removed from storage"),await this._events.unload()}async signinRedirect(r={}){var n;this._logger.create("signinRedirect");const{redirectMethod:s,...a}=r;let c;(n=this.settings.dpop)!=null&&n.bind_authorization_code&&(c=await this.generateDPoPJkt(this.settings.dpop));const f=await this._redirectNavigator.prepare({redirectMethod:s});await this._signinStart({request_type:"si:r",dpopJkt:c,...a},f)}async signinRedirectCallback(r=window.location.href){const n=this._logger.create("signinRedirectCallback"),s=await this._signinEnd(r);return s.profile&&s.profile.sub?n.info("success, signed in subject",s.profile.sub):n.info("no subject"),s}async signinResourceOwnerCredentials({username:r,password:n,skipUserInfo:s=!1}){const a=this._logger.create("signinResourceOwnerCredential"),c=await this._client.processResourceOwnerPasswordCredentials({username:r,password:n,skipUserInfo:s,extraTokenParams:this.settings.extraTokenParams});a.debug("got signin response");const f=await this._buildUser(c);return f.profile&&f.profile.sub?a.info("success, signed in subject",f.profile.sub):a.info("no subject"),f}async signinPopup(r={}){var n;const s=this._logger.create("signinPopup");let a;(n=this.settings.dpop)!=null&&n.bind_authorization_code&&(a=await this.generateDPoPJkt(this.settings.dpop));const{popupWindowFeatures:c,popupWindowTarget:f,popupSignal:p,popupAbortOnClose:v,...y}=r,x=this.settings.popup_redirect_uri;x||s.throw(new Error("No popup_redirect_uri configured"));const R=await this._popupNavigator.prepare({popupWindowFeatures:c,popupWindowTarget:f,popupSignal:p,popupAbortOnClose:v}),N=await this._signin({request_type:"si:p",redirect_uri:x,display:"popup",dpopJkt:a,...y},R);return N&&(N.profile&&N.profile.sub?s.info("success, signed in subject",N.profile.sub):s.info("no subject")),N}async signinPopupCallback(r=window.location.href,n=!1){const s=this._logger.create("signinPopupCallback");await this._popupNavigator.callback(r,{keepOpen:n}),s.info("success")}async signinSilent(r={}){var n,s;const a=this._logger.create("signinSilent"),{silentRequestTimeoutInSeconds:c,...f}=r;let p=await this._loadUser();if(!r.forceIframeAuth&&p?.refresh_token){a.debug("using refresh token");const N=new nS(p);return await this._useRefreshToken({state:N,redirect_uri:f.redirect_uri,resource:f.resource,extraTokenParams:f.extraTokenParams,timeoutInSeconds:c})}let v;(n=this.settings.dpop)!=null&&n.bind_authorization_code&&(v=await this.generateDPoPJkt(this.settings.dpop));const y=this.settings.silent_redirect_uri;y||a.throw(new Error("No silent_redirect_uri configured"));let x;p&&this.settings.validateSubOnSilentRenew&&(a.debug("subject prior to silent renew:",p.profile.sub),x=p.profile.sub);const R=await this._iframeNavigator.prepare({silentRequestTimeoutInSeconds:c});return p=await this._signin({request_type:"si:s",redirect_uri:y,prompt:"none",id_token_hint:this.settings.includeIdTokenInSilentRenew?p?.id_token:void 0,dpopJkt:v,...f},R,x),p&&((s=p.profile)!=null&&s.sub?a.info("success, signed in subject",p.profile.sub):a.info("no subject")),p}async _useRefreshToken(r){const n=await this._client.useRefreshToken({timeoutInSeconds:this.settings.silentRequestTimeoutInSeconds,...r}),s=new cu({...r.state,...n});return await this.storeUser(s),await this._events.load(s),s}async signinSilentCallback(r=window.location.href){const n=this._logger.create("signinSilentCallback");await this._iframeNavigator.callback(r),n.info("success")}async signinCallback(r=window.location.href){const{state:n}=await this._client.readSigninResponseState(r);switch(n.request_type){case"si:r":return await this.signinRedirectCallback(r);case"si:p":await this.signinPopupCallback(r);break;case"si:s":await this.signinSilentCallback(r);break;default:throw new Error("invalid request_type in state")}}async signoutCallback(r=window.location.href,n=!1){const{state:s}=await this._client.readSignoutResponseState(r);if(s)switch(s.request_type){case"so:r":return await this.signoutRedirectCallback(r);case"so:p":await this.signoutPopupCallback(r,n);break;case"so:s":await this.signoutSilentCallback(r);break;default:throw new Error("invalid request_type in state")}}async querySessionStatus(r={}){const n=this._logger.create("querySessionStatus"),{silentRequestTimeoutInSeconds:s,...a}=r,c=this.settings.silent_redirect_uri;c||n.throw(new Error("No silent_redirect_uri configured"));const f=await this._loadUser(),p=await this._iframeNavigator.prepare({silentRequestTimeoutInSeconds:s}),v=await this._signinStart({request_type:"si:s",redirect_uri:c,prompt:"none",id_token_hint:this.settings.includeIdTokenInSilentRenew?f?.id_token:void 0,response_type:this.settings.query_status_response_type,scope:"openid",skipUserInfo:!0,...a},p);try{const y={},x=await this._client.processSigninResponse(v.url,y);return n.debug("got signin response"),x.session_state&&x.profile.sub?(n.info("success for subject",x.profile.sub),{session_state:x.session_state,sub:x.profile.sub}):(n.info("success, user not authenticated"),null)}catch(y){if(this.settings.monitorAnonymousSession&&y instanceof vn)switch(y.error){case"login_required":case"consent_required":case"interaction_required":case"account_selection_required":return n.info("success for anonymous user"),{session_state:y.session_state}}throw y}}async _signin(r,n,s){const a=await this._signinStart(r,n);return await this._signinEnd(a.url,s)}async _signinStart(r,n){const s=this._logger.create("_signinStart");try{const a=await this._client.createSigninRequest(r);return s.debug("got signin request"),await n.navigate({url:a.url,state:a.state.id,response_mode:a.state.response_mode,scriptOrigin:this.settings.iframeScriptOrigin})}catch(a){throw s.debug("error after preparing navigator, closing navigator window"),n.close(),a}}async _signinEnd(r,n){const s=this._logger.create("_signinEnd"),a={},c=await this._client.processSigninResponse(r,a);return s.debug("got signin response"),await this._buildUser(c,n)}async _buildUser(r,n){const s=this._logger.create("_buildUser"),a=new cu(r);if(n){if(n!==a.profile.sub)throw s.debug("current user does not match user returned from signin. sub from signin:",a.profile.sub),new vn({...r,error:"login_required"});s.debug("current user matches user returned from signin")}return await this.storeUser(a),s.debug("user stored"),await this._events.load(a),a}async signoutRedirect(r={}){const n=this._logger.create("signoutRedirect"),{redirectMethod:s,...a}=r,c=await this._redirectNavigator.prepare({redirectMethod:s});await this._signoutStart({request_type:"so:r",post_logout_redirect_uri:this.settings.post_logout_redirect_uri,...a},c),n.info("success")}async signoutRedirectCallback(r=window.location.href){const n=this._logger.create("signoutRedirectCallback"),s=await this._signoutEnd(r);return n.info("success"),s}async signoutPopup(r={}){const n=this._logger.create("signoutPopup"),{popupWindowFeatures:s,popupWindowTarget:a,popupSignal:c,...f}=r,p=this.settings.popup_post_logout_redirect_uri,v=await this._popupNavigator.prepare({popupWindowFeatures:s,popupWindowTarget:a,popupSignal:c});await this._signout({request_type:"so:p",post_logout_redirect_uri:p,state:p==null?void 0:{},...f},v),n.info("success")}async signoutPopupCallback(r=window.location.href,n=!1){const s=this._logger.create("signoutPopupCallback");await this._popupNavigator.callback(r,{keepOpen:n}),s.info("success")}async _signout(r,n){const s=await this._signoutStart(r,n);return await this._signoutEnd(s.url)}async _signoutStart(r={},n){var s;const a=this._logger.create("_signoutStart");try{const c=await this._loadUser();a.debug("loaded current user from storage"),this.settings.revokeTokensOnSignout&&await this._revokeInternal(c);const f=r.id_token_hint||c&&c.id_token;f&&(a.debug("setting id_token_hint in signout request"),r.id_token_hint=f),await this.removeUser(),a.debug("user removed, creating signout request");const p=await this._client.createSignoutRequest(r);return a.debug("got signout request"),await n.navigate({url:p.url,state:(s=p.state)==null?void 0:s.id,scriptOrigin:this.settings.iframeScriptOrigin})}catch(c){throw a.debug("error after preparing navigator, closing navigator window"),n.close(),c}}async _signoutEnd(r){const n=this._logger.create("_signoutEnd"),s=await this._client.processSignoutResponse(r);return n.debug("got signout response"),s}async signoutSilent(r={}){var n;const s=this._logger.create("signoutSilent"),{silentRequestTimeoutInSeconds:a,...c}=r,f=this.settings.includeIdTokenInSilentSignout?(n=await this._loadUser())==null?void 0:n.id_token:void 0,p=this.settings.popup_post_logout_redirect_uri,v=await this._iframeNavigator.prepare({silentRequestTimeoutInSeconds:a});await this._signout({request_type:"so:s",post_logout_redirect_uri:p,id_token_hint:f,...c},v),s.info("success")}async signoutSilentCallback(r=window.location.href){const n=this._logger.create("signoutSilentCallback");await this._iframeNavigator.callback(r),n.info("success")}async revokeTokens(r){const n=await this._loadUser();await this._revokeInternal(n,r)}async _revokeInternal(r,n=this.settings.revokeTokenTypes){const s=this._logger.create("_revokeInternal");if(!r)return;const a=n.filter(c=>typeof r[c]=="string");if(!a.length){s.debug("no need to revoke due to no token(s)");return}for(const c of a)await this._client.revokeToken(r[c],c),s.info(`${c} revoked successfully`),c!=="access_token"&&(r[c]=null);await this.storeUser(r),s.debug("user stored"),await this._events.load(r)}startSilentRenew(){this._logger.create("startSilentRenew"),this._silentRenewService.start()}stopSilentRenew(){this._silentRenewService.stop()}get _userStoreKey(){return`user:${this.settings.authority}:${this.settings.client_id}`}async _loadUser(){const r=this._logger.create("_loadUser"),n=await this.settings.userStore.get(this._userStoreKey);return n?(r.debug("user storageString loaded"),cu.fromStorageString(n)):(r.debug("no user storageString"),null)}async storeUser(r){const n=this._logger.create("storeUser");if(r){n.debug("storing user");const s=r.toStorageString();await this.settings.userStore.set(this._userStoreKey,s)}else this._logger.debug("removing user"),await this.settings.userStore.remove(this._userStoreKey),this.settings.dpop&&await this.settings.dpop.store.remove(this.settings.client_id)}async clearStaleState(){await this._client.clearStaleState()}async dpopProof(r,n,s,a){var c,f;const p=await((f=(c=this.settings.dpop)==null?void 0:c.store)==null?void 0:f.get(this.settings.client_id));if(p)return await Je.generateDPoPProof({url:r,accessToken:n?.access_token,httpMethod:s,keyPair:p.keys,nonce:a})}async generateDPoPJkt(r){let n=await r.store.get(this.settings.client_id);if(!n){const s=await Je.generateDPoPKeys();n=new yp(s),await r.store.set(this.settings.client_id,n)}return await Je.generateDPoPJkt(n.keys)}},Hu=Tt.createContext(void 0);Hu.displayName="AuthContext";var sS={isLoading:!0,isAuthenticated:!1},oS=(r,n)=>{switch(n.type){case"INITIALISED":case"USER_LOADED":return{...r,user:n.user,isLoading:!1,isAuthenticated:n.user?!n.user.expired:!1,error:void 0};case"USER_SIGNED_OUT":case"USER_UNLOADED":return{...r,user:void 0,isAuthenticated:!1};case"NAVIGATOR_INIT":return{...r,isLoading:!0,activeNavigator:n.method};case"NAVIGATOR_CLOSE":return{...r,isLoading:!1,activeNavigator:void 0};case"ERROR":{const s=n.error;return s.toString=()=>`${s.name}: ${s.message}`,{...r,isLoading:!1,error:s}}default:{const s=new TypeError(`unknown type ${n.type}`),a={name:s.name,message:s.message,innerError:s,stack:s.stack,source:"unknown"};return a.toString=()=>`${a.name}: ${a.message}`,{...r,isLoading:!1,error:a}}}},aS=(r=window.location)=>{let n=new URLSearchParams(r.search);return!!((n.get("code")||n.get("error"))&&n.get("state")||(n=new URLSearchParams(r.hash.replace("#","?")),(n.get("code")||n.get("error"))&&n.get("state")))},lS=Ku("signinCallback","Sign-in failed"),uS=Ku("signoutCallback","Sign-out failed"),cS=Ku("renewSilent","Renew silent failed");function kp(r,n){return{name:du(r,"name",()=>"Error"),message:du(r,"message",()=>n),stack:du(r,"stack",()=>new Error().stack),innerError:r}}function Ku(r,n){return s=>({...kp(s,n),source:r})}function du(r,n,s){if(r&&typeof r=="object"){const a=r[n];if(typeof a=="string")return a}return s()}var dS=["clearStaleState","querySessionStatus","revokeTokens","startSilentRenew","stopSilentRenew"],fS=["signinPopup","signinSilent","signinRedirect","signinResourceOwnerCredentials","signoutPopup","signoutRedirect","signoutSilent"],gh=r=>()=>{throw new Error(`UserManager#${r} was called from an unsupported context. If this is a server-rendered page, defer this call with useEffect() or pass a custom UserManager implementation.`)},mh=typeof window>"u"?null:iS,hS=r=>{const{children:n,onSigninCallback:s,skipSigninCallback:a,matchSignoutCallback:c,onSignoutCallback:f,onRemoveUser:p,userManager:v=null,...y}=r,[x]=Tt.useState(()=>v??(mh?new mh(y):{settings:y})),[R,N]=Tt.useReducer(oS,sS),j=Tt.useMemo(()=>Object.assign({settings:x.settings,events:x.events},Object.fromEntries(dS.map($=>{var fe,T;return[$,(T=(fe=x[$])==null?void 0:fe.bind(x))!=null?T:gh($)]})),Object.fromEntries(fS.map($=>[$,x[$]?async fe=>{N({type:"NAVIGATOR_INIT",method:$});try{return await x[$](fe)}catch(T){return N({type:"ERROR",error:{...kp(T,`Unknown error while executing ${$}(...).`),source:$,args:fe}}),null}finally{N({type:"NAVIGATOR_CLOSE"})}}:gh($)]))),[x]),O=Tt.useRef(!1);Tt.useEffect(()=>{!x||O.current||(O.current=!0,(async()=>{try{let $=null;aS()&&!a&&($=await x.signinCallback(),s&&await s($)),$=$||await x.getUser(),N({type:"INITIALISED",user:$})}catch($){N({type:"ERROR",error:lS($)})}try{if(c&&c(x.settings)){const $=await x.signoutCallback();f&&await f($)}}catch($){N({type:"ERROR",error:uS($)})}})())},[x,a,s,f,c]),Tt.useEffect(()=>{if(!x)return;const $=L=>{N({type:"USER_LOADED",user:L})};x.events.addUserLoaded($);const fe=()=>{N({type:"USER_UNLOADED"})};x.events.addUserUnloaded(fe);const T=()=>{N({type:"USER_SIGNED_OUT"})};x.events.addUserSignedOut(T);const A=L=>{N({type:"ERROR",error:cS(L)})};return x.events.addSilentRenewError(A),()=>{x.events.removeUserLoaded($),x.events.removeUserUnloaded(fe),x.events.removeUserSignedOut(T),x.events.removeSilentRenewError(A)}},[x]);const q=Tt.useCallback(async()=>{await x.removeUser(),p&&await p()},[x,p]),Q=Tt.useMemo(()=>({...R,...j,removeUser:q}),[R,j,q]);return Tt.createElement(Hu.Provider,{value:Q},n)},bp=()=>{const r=Tt.useContext(Hu);return r||console.warn("AuthProvider context is undefined, please verify you are calling useAuth() as child of a component."),r};function pS(){const{identity:r,isActive:n}=Lu(),s=bp(),[a,c]=ae.useState(null),[f,p]=ae.useState(null),[v,y]=ae.useState(null),[x,R]=ae.useState(""),[N,j]=ae.useState(""),[O,q]=ae.useState(!1),[Q,$]=ae.useState(""),[fe,T]=ae.useState(!1),[A,L]=ae.useState(""),[J,Y]=ae.useState(!1),[ge,me]=ae.useState(!1),[ue,Re]=ae.useState(""),[We,Le]=ae.useState("oidc"),[Me,it]=ae.useState(""),[ke,P]=ae.useState(""),[W,M]=ae.useState(""),H=Tt.useRef(null),z=Tt.useRef(null),w=hr(fr.setName),E=hr(fr.createServer),ee=hr(fr.createChannel),ne=hr(fr.createThread),te=hr(fr.sendMessage),le=hr(fr.register),ie=hr(fr.login),he=hr(fr.joinVoice),we=hr(fr.leaveVoice),[_e]=pi(fi.server),[Ne]=pi(fi.channel),[Ge,Dt]=pi(fi.user),[mr]=pi(fi.message),[Dr]=pi(fi.thread),[Sn]=pi(fi.voice_state);ae.useEffect(()=>{!a&&_e.length>0&&c(_e[0].id)},[_e,a]),ae.useEffect(()=>{if(a){const B=Ne.filter(ye=>ye.serverId===a&&ye.kind.tag==="Text");B.length>0&&(!f||!Ne.some(ye=>ye.id===f&&ye.serverId===a))&&p(B[0].id)}},[a,Ne]);const zr=ae.useMemo(()=>_e.find(B=>B.id===a),[_e,a]),Ui=ae.useMemo(()=>Ne.find(B=>B.id===f),[Ne,f]),Ri=ae.useMemo(()=>Dr.find(B=>B.id===v),[Dr,v]),Fr=ae.useMemo(()=>a?Ne.filter(B=>B.serverId===a&&B.kind.tag==="Text"):[],[Ne,a]),yr=ae.useMemo(()=>a?Ne.filter(B=>B.serverId===a&&B.kind.tag==="Voice"):[],[Ne,a]),xn=ae.useMemo(()=>f?mr.filter(B=>B.channelId===f&&B.threadId===void 0).sort((B,ye)=>B.sent.microsSinceUnixEpochv?mr.filter(B=>B.threadId===v).sort((B,ye)=>B.sent.microsSinceUnixEpochGe.find(B=>B.identity.isEqual(r||Bs.zero())),[Ge,r]),In=ae.useMemo(()=>Sn.find(B=>B.identity.isEqual(r||Bs.zero())),[Sn,r]),Pi=ae.useMemo(()=>Ne.find(B=>B.id===In?.channelId),[Ne,In]),kn=ae.useMemo(()=>Ge.filter(B=>B.online),[Ge]),xt=ae.useMemo(()=>{if(!St)return!1;const B=!!(St.issuer&&St.subject),ye=!!(St.username&&St.password);return B||ye},[St]);ae.useEffect(()=>{H.current?.scrollIntoView({behavior:"smooth"})},[xn]),ae.useEffect(()=>{z.current?.scrollIntoView({behavior:"smooth"})},[Ni]);const js=B=>{B.preventDefault(),!(!x.trim()||!f)&&(te({text:x,channelId:f,threadId:void 0}),R(""))},$r=B=>{B.preventDefault(),!(!N.trim()||!v||!f)&&(te({text:N,channelId:f,threadId:v}),j(""))},Lr=B=>{B.preventDefault(),Q.trim()&&(E({name:Q}),$(""),q(!1))},ya=B=>{B.preventDefault(),!(!A.trim()||!a)&&(ee({name:A,serverId:a,isVoice:J}),L(""),Y(!1),T(!1))},Os=B=>{B.preventDefault(),ue.trim()&&(w({name:ue}),me(!1))},Ds=B=>{const ye=`Thread on: ${B.text.substring(0,20)}...`;ne({name:ye,channelId:B.channelId,parentMessageId:B.id})},wa=B=>{B.preventDefault(),M(""),ie({username:Me,password:ke}).catch(ye=>M(ye.message||"Login failed"))},Bi=B=>{B.preventDefault(),M(""),le({username:Me,password:ke}).then(()=>{Le("login"),M("Registration successful! Please log in.")}).catch(ye=>M(ye.message||"Registration failed"))},Ai=B=>{he({channelId:B})};if(s.isLoading)return b.jsx("div",{className:"login-screen",children:b.jsxs("div",{className:"login-card",children:[b.jsx("h1",{children:"Loading Authentication..."}),b.jsx("p",{children:"Please wait while we prepare your session."})]})});if(!n||!r)return b.jsx("div",{className:"login-screen",children:b.jsxs("div",{className:"login-card",children:[b.jsx("h1",{children:"Connecting..."}),b.jsx("p",{children:"Establishing connection to SpacetimeDB server."}),b.jsx("div",{className:"avatar",style:{width:"48px",height:"48px",fontSize:"1.2rem"},children:"..."})]})});if(!Dt)return b.jsx("div",{className:"login-screen",children:b.jsxs("div",{className:"login-card",children:[b.jsx("h1",{children:"Loading User Data..."}),b.jsx("p",{children:"Fetching your profile from the server."}),b.jsx("div",{className:"avatar",style:{width:"48px",height:"48px",fontSize:"1.2rem"},children:"..."})]})});if(!(s.isAuthenticated||xt))return b.jsx("div",{className:"login-screen",children:b.jsxs("div",{className:"login-card",children:[b.jsx("h1",{children:"Welcome to Spacetime Discord"}),b.jsx("p",{style:{marginBottom:"10px"},children:"Authentication is required to enter the community."}),b.jsxs("div",{style:{width:"100%",display:"flex",flexDirection:"column",gap:"20px"},children:[b.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"10px"},children:[b.jsx("h3",{style:{margin:0,fontSize:"0.9rem",color:"var(--text-muted)"},children:"FAST TRACK"}),b.jsxs("button",{className:"btn-primary",style:{width:"100%",display:"flex",alignItems:"center",justifyContent:"center",gap:"10px"},onClick:()=>s.signinRedirect(),children:[b.jsx("span",{style:{fontSize:"1.2rem"},children:"🌐"})," Log In with OIDC"]})]}),b.jsxs("div",{style:{display:"flex",alignItems:"center",width:"100%",gap:"10px"},children:[b.jsx("div",{style:{flex:1,height:"1px",backgroundColor:"var(--background-accent)"}}),b.jsx("span",{style:{fontSize:"0.8rem",color:"var(--text-muted)"},children:"OR USE CREDENTIALS"}),b.jsx("div",{style:{flex:1,height:"1px",backgroundColor:"var(--background-accent)"}})]}),b.jsxs("form",{onSubmit:We==="register"?Bi:wa,style:{width:"100%",display:"flex",flexDirection:"column",gap:"16px"},children:[b.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"8px"},children:[b.jsx("label",{style:{fontSize:"0.8rem",fontWeight:"bold",color:"var(--text-muted)"},children:"USERNAME"}),b.jsx("input",{autoFocus:!0,className:"chat-input",style:{backgroundColor:"var(--background-tertiary)",borderRadius:"4px",padding:"10px"},value:Me,onChange:B=>it(B.target.value)})]}),b.jsxs("div",{style:{display:"flex",flexDirection:"column",gap:"8px"},children:[b.jsx("label",{style:{fontSize:"0.8rem",fontWeight:"bold",color:"var(--text-muted)"},children:"PASSWORD"}),b.jsx("input",{type:"password",className:"chat-input",style:{backgroundColor:"var(--background-tertiary)",borderRadius:"4px",padding:"10px"},value:ke,onChange:B=>P(B.target.value)})]}),W&&b.jsx("div",{style:{color:"#da373c",fontSize:"0.85rem",textAlign:"center"},children:W}),b.jsx("button",{type:"submit",className:"btn-secondary",style:{width:"100%",backgroundColor:"var(--background-accent)"},children:We==="register"?"Create Account":"Log In"}),b.jsxs("div",{style:{fontSize:"0.9rem",color:"var(--text-muted)",textAlign:"center"},children:[We==="login"?"Need an account? ":"Already have an account? ",b.jsx("span",{style:{color:"var(--brand)",cursor:"pointer",fontWeight:"bold"},onClick:()=>{Le(We==="login"?"register":"login"),M("")},children:We==="login"?"Register":"Log In"})]})]})]})]})});const Et=B=>Ge.find(bn=>bn.identity.isEqual(B))?.name||B.toHexString().substring(0,8),Mi=B=>new Date(Number(B.microsSinceUnixEpoch/1000n)).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});return b.jsxs("div",{className:"app-container",children:[b.jsxs("div",{className:"server-sidebar",children:[_e.map(B=>b.jsx("div",{className:`server-icon ${a===B.id?"active":""}`,onClick:()=>{c(B.id),y(null)},title:B.name,children:B.name.substring(0,2).toUpperCase()},B.id.toString())),b.jsx("div",{className:"server-icon",onClick:()=>q(!0),children:"+"})]}),b.jsxs("div",{className:"channel-sidebar",children:[b.jsxs("div",{className:"channel-header",style:{justifyContent:"space-between"},children:[b.jsx("span",{style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:zr?.name||"No Server Selected"}),zr&&b.jsx("button",{className:"add-btn",onClick:()=>T(!0),children:"+"})]}),b.jsxs("div",{className:"channel-list",children:[b.jsx("div",{style:{fontSize:"0.7rem",fontWeight:"bold",color:"var(--text-muted)",padding:"8px 8px 4px 8px"},children:"TEXT CHANNELS"}),Fr.map(B=>b.jsxs("div",{className:`channel-item ${f===B.id?"active":""}`,onClick:()=>{p(B.id),y(null)},children:[b.jsx("span",{className:"channel-item-hash",children:"#"}),B.name]},B.id.toString())),b.jsx("div",{style:{fontSize:"0.7rem",fontWeight:"bold",color:"var(--text-muted)",padding:"16px 8px 4px 8px"},children:"VOICE CHANNELS"}),yr.map(B=>b.jsxs("div",{children:[b.jsxs("div",{className:`channel-item ${In?.channelId===B.id?"active":""}`,onClick:()=>Ai(B.id),children:[b.jsx("span",{className:"channel-item-hash",children:"🔊"}),B.name]}),b.jsx("div",{style:{marginLeft:"24px",display:"flex",flexDirection:"column",gap:"4px",marginBottom:"8px"},children:Sn.filter(ye=>ye.channelId===B.id).map(ye=>b.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"6px",fontSize:"0.85rem",color:"var(--text-muted)"},children:[b.jsx("div",{className:"avatar",style:{width:"18px",height:"18px",fontSize:"0.5rem"},children:Et(ye.identity).substring(0,2).toUpperCase()}),Et(ye.identity)]},ye.identity.toHexString()))})]},B.id.toString()))]}),Pi&&b.jsxs("div",{style:{backgroundColor:"#232428",borderBottom:"1px solid rgba(255,255,255,0.05)",padding:"10px",display:"flex",alignItems:"center",justifyContent:"space-between"},children:[b.jsxs("div",{style:{display:"flex",flexDirection:"column"},children:[b.jsx("span",{style:{color:"#23a559",fontSize:"0.8rem",fontWeight:"bold"},children:"Voice Connected"}),b.jsxs("span",{style:{color:"var(--text-muted)",fontSize:"0.75rem"},children:[Pi.name," / ",zr?.name]})]}),b.jsx("button",{className:"add-btn",style:{color:"#da373c"},onClick:()=>we(),children:"📞"})]}),b.jsxs("div",{className:"user-profile",children:[b.jsx("div",{className:"avatar",children:Et(r).substring(0,2).toUpperCase()}),b.jsxs("div",{className:"user-info",children:[b.jsx("div",{className:"username",children:Et(r)}),b.jsx("div",{className:"user-status",children:xt?"Online":"Unlinked Account"})]}),b.jsx("button",{className:"add-btn",onClick:()=>{Re(St?.name||""),me(!0)},children:"⚙️"})]})]}),b.jsxs("div",{className:"main-content",children:[b.jsxs("div",{className:"chat-header",children:[b.jsx("span",{style:{color:"var(--text-muted)",marginRight:"8px"},children:"#"}),Ui?.name||"Select a channel"]}),b.jsxs("div",{className:"messages-container",children:[xn.map(B=>b.jsxs("div",{className:"message",children:[b.jsx("div",{className:"message-avatar",children:Et(B.sender).substring(0,2).toUpperCase()}),b.jsxs("div",{className:"message-content",children:[b.jsxs("div",{className:"message-meta",children:[b.jsx("span",{className:"message-sender",children:Et(B.sender)}),b.jsx("span",{className:"message-timestamp",children:Mi(B.sent)})]}),b.jsx("div",{className:"message-text",children:B.text}),(()=>{const ye=Dr.find(bn=>bn.parentMessageId===B.id);return ye?b.jsx("button",{className:"message-thread-btn",onClick:()=>y(ye.id),children:"View Thread"}):b.jsx("button",{className:"message-thread-btn",onClick:()=>Ds(B),children:"Start Thread"})})(),Dr.filter(ye=>ye.parentMessageId===B.id).map(ye=>b.jsxs("div",{style:{marginLeft:"12px",marginTop:"4px",cursor:"pointer",color:"var(--brand)"},onClick:()=>y(ye.id),children:["↳ ",ye.name]},ye.id.toString()))]})]},B.id.toString())),b.jsx("div",{ref:H})]}),b.jsx("div",{className:"chat-input-container",children:b.jsx("form",{className:"chat-input-wrapper",onSubmit:js,children:b.jsx("input",{className:"chat-input",placeholder:xt?`Message #${Ui?.name||""}`:"Log in to chat",disabled:!xt,value:x,onChange:B=>R(B.target.value)})})})]}),b.jsx("div",{className:"right-sidebar",children:v?b.jsxs("div",{className:"thread-view",children:[b.jsxs("div",{className:"thread-header",children:[b.jsx("span",{children:"Thread"}),b.jsx("button",{className:"close-btn",onClick:()=>y(null),children:"×"})]}),b.jsxs("div",{className:"thread-messages",children:[b.jsx("div",{style:{padding:"8px",borderBottom:"1px solid var(--background-accent)",marginBottom:"8px"},children:b.jsx("div",{style:{fontWeight:"bold"},children:Ri?.name})}),Ni.map(B=>b.jsxs("div",{className:"message",style:{gap:"8px",marginBottom:"8px"},children:[b.jsx("div",{className:"message-avatar",style:{width:"32px",height:"32px"},children:Et(B.sender).substring(0,2).toUpperCase()}),b.jsxs("div",{className:"message-content",children:[b.jsx("div",{className:"message-meta",children:b.jsx("span",{className:"message-sender",style:{fontSize:"0.9rem"},children:Et(B.sender)})}),b.jsx("div",{className:"message-text",style:{fontSize:"0.9rem"},children:B.text})]})]},B.id.toString())),b.jsx("div",{ref:z})]}),b.jsx("div",{className:"chat-input-container",style:{padding:"8px"},children:b.jsx("form",{className:"chat-input-wrapper",onSubmit:$r,children:b.jsx("input",{className:"chat-input",style:{fontSize:"0.85rem"},placeholder:xt?"Reply in thread...":"Log in to chat",disabled:!xt,value:N,onChange:B=>j(B.target.value)})})})]}):b.jsxs("div",{className:"member-list",children:[b.jsxs("div",{style:{padding:"0 8px 8px 8px",fontSize:"0.75rem",fontWeight:"bold",color:"var(--text-muted)"},children:["ONLINE — ",kn.length]}),kn.map(B=>b.jsxs("div",{className:"member-item",children:[b.jsx("div",{className:"member-avatar",style:{width:"24px",height:"24px",display:"flex",alignItems:"center",justifyContent:"center",color:"white",fontSize:"0.7rem"},children:(B.name||B.identity.toHexString()).substring(0,2).toUpperCase()}),b.jsx("span",{className:"member-name",children:B.name||B.identity.toHexString().substring(0,8)})]},B.identity.toHexString()))]})}),O&&b.jsx("div",{className:"modal-overlay",children:b.jsxs("form",{className:"modal-content",onSubmit:Lr,children:[b.jsx("h2",{children:"Create Server"}),b.jsx("input",{autoFocus:!0,placeholder:"server-name",value:Q,onChange:B=>$(B.target.value)}),b.jsxs("div",{className:"modal-buttons",children:[b.jsx("button",{type:"button",className:"btn-secondary",onClick:()=>q(!1),children:"Cancel"}),b.jsx("button",{type:"submit",className:"btn-primary",disabled:!xt,children:"Create"})]})]})}),fe&&b.jsx("div",{className:"modal-overlay",children:b.jsxs("form",{className:"modal-content",onSubmit:ya,children:[b.jsx("h2",{children:"Create Channel"}),b.jsx("input",{autoFocus:!0,placeholder:"channel-name",value:A,onChange:B=>L(B.target.value)}),b.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px",color:"var(--text-normal)"},children:[b.jsx("input",{type:"checkbox",checked:J,onChange:B=>Y(B.target.checked)}),b.jsx("label",{children:"Voice Channel"})]}),b.jsxs("div",{className:"modal-buttons",children:[b.jsx("button",{type:"button",className:"btn-secondary",onClick:()=>T(!1),children:"Cancel"}),b.jsx("button",{type:"submit",className:"btn-primary",disabled:!xt,children:"Create"})]})]})}),ge&&b.jsx("div",{className:"modal-overlay",children:b.jsxs("form",{className:"modal-content",onSubmit:Os,children:[b.jsx("h2",{children:"Account Settings"}),b.jsx("input",{autoFocus:!0,placeholder:"Display Name",value:ue,onChange:B=>Re(B.target.value)}),b.jsx("div",{style:{fontSize:"0.8rem",color:"var(--text-muted)",marginTop:"8px"},children:St?.issuer?b.jsxs(b.Fragment,{children:["Signed in via OIDC as: ",b.jsx("b",{children:s.user?.profile.name||s.user?.profile.sub})]}):St?.username?b.jsxs(b.Fragment,{children:["Logged in as: ",b.jsx("b",{children:St.username})]}):b.jsx(b.Fragment,{children:"Unlinked Anonymous Account"})}),b.jsxs("div",{className:"modal-buttons",style:{marginTop:"16px",justifyContent:"space-between"},children:[b.jsx("button",{type:"button",className:"btn-danger",onClick:()=>{s.isAuthenticated&&s.signoutRedirect(),localStorage.removeItem(Wu),window.location.reload()},children:"Sign Out / Reset"}),b.jsxs("div",{style:{display:"flex",gap:"8px"},children:[b.jsx("button",{type:"button",className:"btn-secondary",onClick:()=>me(!1),children:"Cancel"}),b.jsx("button",{type:"submit",className:"btn-primary",children:"Save"})]})]})]})})]})}const Cp="https://maincloud.spacetimedb.com",Tp="my-spacetime-app-jdhdg",Wu=`${Cp}/${Tp}/auth_token`,gS={authority:"https://accounts.google.com",client_id:"REPLACE_ME",redirect_uri:window.location.origin,scope:"openid profile email",response_type:"code",onSigninCallback:()=>{window.history.replaceState({},document.title,window.location.pathname)}},mS=(r,n,s)=>{localStorage.setItem(Wu,s),console.log("Connected to SpacetimeDB with identity:",n.toHexString())},yS=()=>{console.log("Disconnected from SpacetimeDB")},wS=(r,n)=>{console.log("Error connecting to SpacetimeDB:",n)};function vS(){const r=bp(),n=ae.useMemo(()=>{const s=Fu.builder().withUri(Cp).withDatabaseName(Tp).onConnect(mS).onDisconnect(yS).onConnectError(wS);if(r.isAuthenticated&&r.user?.id_token)return console.log("Connecting with OIDC token"),s.withToken(r.user.id_token);{const a=localStorage.getItem(Wu);if(a)return console.log("Connecting with stored SpacetimeDB token"),s.withToken(a)}return s},[r.isAuthenticated,r.user?.id_token]);return b.jsx(x_,{connectionBuilder:n,children:b.jsx(pS,{})})}Rm.createRoot(document.getElementById("root")).render(b.jsx(ae.StrictMode,{children:b.jsx(hS,{...gS,children:b.jsx(vS,{})})})); diff --git a/dist/assets/index-a-MKc3No.css b/dist/assets/index-a-MKc3No.css new file mode 100644 index 0000000..6ba8230 --- /dev/null +++ b/dist/assets/index-a-MKc3No.css @@ -0,0 +1 @@ +*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}:root{--theme-color: #3dc373;--theme-color-contrast: #08180e;--textbox-color: #edfef4;color-scheme:light dark}@media(prefers-color-scheme:dark){:root{--theme-color: #4cf490;--theme-color-contrast: #132219;--textbox-color: #0f311d}}html,body,#root{height:100%;margin:0}body{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}button{padding:.5rem .75rem;border:none;border-radius:.375rem;background-color:var(--theme-color);color:var(--theme-color-contrast);cursor:pointer;font-weight:600;letter-spacing:.1px;font-family:monospace}input,textarea{border:none;border-radius:.375rem;caret-color:var(--theme-color);font-family:monospace;font-weight:600;letter-spacing:.1px;padding:.5rem .75rem}input:focus,textarea:focus{outline:none;box-shadow:0 0 0 2px var(--theme-color)}:root{--background-primary: #313338;--background-secondary: #2b2d31;--background-tertiary: #1e1f22;--background-accent: #404249;--channel-sidebar-width: 240px;--server-sidebar-width: 72px;--text-normal: #dbdee1;--text-muted: #949ba4;--header-primary: #ffffff;--interactive-normal: #b5bac1;--interactive-hover: #dbdee1;--interactive-active: #ffffff;--brand: #5865f2;--brand-hover: #4752c4}body{margin:0;padding:0;background-color:var(--background-tertiary);color:var(--text-normal);font-family:gg sans,Noto Sans,Helvetica Neue,Helvetica,Arial,sans-serif;overflow:hidden}.app-container{display:flex;height:100vh;width:100vw}.login-screen{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100vh;width:100vw;background-color:var(--background-tertiary);gap:20px}.login-card{background-color:var(--background-primary);padding:32px;border-radius:8px;box-shadow:0 2px 10px #0003;display:flex;flex-direction:column;align-items:center;gap:24px;width:400px}.login-card h1{margin:0;color:var(--header-primary)}.login-card p{color:var(--text-muted);text-align:center;margin:0}.server-sidebar{width:var(--server-sidebar-width);background-color:var(--background-tertiary);display:flex;flex-direction:column;align-items:center;padding-top:12px;gap:8px}.server-icon{width:48px;height:48px;background-color:var(--background-accent);border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:border-radius .2s,background-color .2s;color:var(--text-normal)}.server-icon:hover,.server-icon.active{border-radius:16px;background-color:var(--brand)}.channel-sidebar{width:var(--channel-sidebar-width);background-color:var(--background-secondary);display:flex;flex-direction:column}.channel-header{height:48px;padding:0 16px;display:flex;align-items:center;box-shadow:0 1px #0003;font-weight:700;color:var(--header-primary)}.channel-list{flex:1;padding:8px;overflow-y:auto}.channel-item{padding:6px 8px;border-radius:4px;cursor:pointer;display:flex;align-items:center;color:var(--interactive-normal);margin-bottom:2px}.channel-item:hover{background-color:var(--background-accent);color:var(--interactive-hover)}.channel-item.active{background-color:var(--background-accent);color:var(--interactive-active)}.channel-item-hash{margin-right:6px;color:var(--text-muted);font-size:1.2rem}.user-profile{height:52px;background-color:#232428;display:flex;align-items:center;padding:0 8px;gap:8px}.avatar{width:32px;height:32px;background-color:#5865f2;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.8rem;color:#fff}.user-info{flex:1;overflow:hidden}.username{font-size:.85rem;font-weight:600;color:var(--header-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.user-status{font-size:.75rem;color:var(--text-muted)}.main-content{flex:1;display:flex;flex-direction:column;background-color:var(--background-primary)}.chat-header{height:48px;padding:0 16px;display:flex;align-items:center;box-shadow:0 1px #0003;color:var(--header-primary);font-weight:700}.messages-container{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:16px}.message{display:flex;gap:16px}.message-avatar{width:40px;height:40px;background-color:#5865f2;border-radius:50%;margin-top:2px;flex-shrink:0;display:flex;align-items:center;justify-content:center;color:#fff}.message-content{flex:1}.message-meta{display:flex;align-items:baseline;gap:8px;margin-bottom:4px}.message-sender{font-weight:500;color:var(--header-primary)}.message-timestamp{font-size:.75rem;color:var(--text-muted)}.message-text{color:var(--text-normal);line-height:1.375rem;word-wrap:break-word}.message-thread-btn{font-size:.75rem;color:var(--brand);background:none;border:none;cursor:pointer;padding:0;margin-top:4px}.message-thread-btn:hover{text-decoration:underline}.chat-input-container{padding:0 16px 24px}.chat-input-wrapper{background-color:#383a40;border-radius:8px;padding:11px 16px;display:flex;align-items:center}.chat-input{flex:1;background:none;border:none;color:var(--text-normal);font-family:inherit;font-size:1rem;outline:none}.chat-input::placeholder{color:var(--text-muted)}.right-sidebar{width:240px;background-color:var(--background-secondary);display:flex;flex-direction:column;border-left:1px solid rgba(255,255,255,.05)}.thread-view{display:flex;flex-direction:column;height:100%}.thread-header{height:48px;padding:0 16px;display:flex;align-items:center;justify-content:space-between;box-shadow:0 1px #0003;font-weight:700}.close-btn{background:none;border:none;color:var(--interactive-normal);cursor:pointer;font-size:1.2rem}.thread-messages{flex:1;overflow-y:auto;padding:8px}.member-list{padding:16px 8px}.member-item{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:4px;color:var(--text-muted)}.member-item:hover{background-color:var(--background-accent);color:var(--interactive-hover)}.member-avatar{width:32px;height:32px;background-color:#5865f2;border-radius:50%}.member-name{font-size:.9rem;font-weight:500}.modal-overlay{position:fixed;inset:0;background-color:#000000d9;display:flex;align-items:center;justify-content:center;z-index:1000}.modal-content{background-color:var(--background-primary);padding:24px;border-radius:8px;width:400px;display:flex;flex-direction:column;gap:16px}.modal-content h2{margin:0;color:var(--header-primary)}.modal-content input{background-color:var(--background-tertiary);border:none;padding:12px;border-radius:4px;color:var(--text-normal);outline:none}.modal-buttons{display:flex;justify-content:flex-end;gap:8px}.btn-primary{background-color:var(--brand);color:#fff;border:none;padding:10px 20px;border-radius:4px;cursor:pointer}.btn-secondary{background-color:transparent;color:#fff;border:none;padding:10px 20px;cursor:pointer}.btn-danger{background-color:#da373c;color:#fff;border:none;padding:10px 20px;border-radius:4px;cursor:pointer}.btn-danger:hover{background-color:#a12829}.add-btn{background:none;border:none;color:var(--interactive-normal);cursor:pointer;font-size:1.2rem} diff --git a/dist/index.html b/dist/index.html new file mode 100644 index 0000000..0a1ec71 --- /dev/null +++ b/dist/index.html @@ -0,0 +1,14 @@ + + + + + + + Vite + React + TS + + + + +
+ + diff --git a/dist/vite.svg b/dist/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/dist/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..e4b78ea --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + React + TS + + +
+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..bc3c3c0 --- /dev/null +++ b/package.json @@ -0,0 +1,45 @@ +{ + "name": "my-spacetime-app", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "format": "prettier . --write --ignore-path ../../.prettierignore", + "lint": "eslint . && prettier . --check --ignore-path ../../.prettierignore", + "preview": "vite preview", + "test": "vitest run", + "generate": "cargo run -p gen-bindings -- --out-dir src/module_bindings --module-path spacetimedb && prettier --write src/module_bindings", + "spacetime:generate": "spacetime generate --lang typescript --out-dir src/module_bindings --module-path spacetimedb", + "spacetime:publish:local": "spacetime publish --module-path server --server local", + "spacetime:publish": "spacetime publish --module-path server --server maincloud" + }, + "dependencies": { + "oidc-client-ts": "^3.5.0", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-oidc-context": "^3.3.1", + "spacetimedb": "^2.1.0" + }, + "devDependencies": { + "@eslint/js": "^9.17.0", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.2.0", + "@testing-library/user-event": "^14.6.1", + "@types/react": "^18.3.18", + "@types/react-dom": "^18.3.5", + "@vitejs/plugin-basic-ssl": "^2.3.0", + "@vitejs/plugin-react": "^5.0.2", + "eslint": "^9.17.0", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.16", + "globals": "^15.14.0", + "jsdom": "^26.0.0", + "prettier": "^3.3.3", + "typescript": "~5.6.2", + "typescript-eslint": "^8.18.2", + "vite": "^7.1.5", + "vitest": "3.2.4" + } +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..8602592 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,2993 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + oidc-client-ts: + specifier: ^3.5.0 + version: 3.5.0 + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + react-oidc-context: + specifier: ^3.3.1 + version: 3.3.1(oidc-client-ts@3.5.0)(react@18.3.1) + spacetimedb: + specifier: ^2.1.0 + version: 2.1.0(react@18.3.1) + devDependencies: + '@eslint/js': + specifier: ^9.17.0 + version: 9.39.4 + '@testing-library/jest-dom': + specifier: ^6.6.3 + version: 6.9.1 + '@testing-library/react': + specifier: ^16.2.0 + version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@testing-library/user-event': + specifier: ^14.6.1 + version: 14.6.1(@testing-library/dom@10.4.1) + '@types/react': + specifier: ^18.3.18 + version: 18.3.28 + '@types/react-dom': + specifier: ^18.3.5 + version: 18.3.7(@types/react@18.3.28) + '@vitejs/plugin-basic-ssl': + specifier: ^2.3.0 + version: 2.3.0(vite@7.3.1) + '@vitejs/plugin-react': + specifier: ^5.0.2 + version: 5.2.0(vite@7.3.1) + eslint: + specifier: ^9.17.0 + version: 9.39.4 + eslint-plugin-react-hooks: + specifier: ^5.0.0 + version: 5.2.0(eslint@9.39.4) + eslint-plugin-react-refresh: + specifier: ^0.4.16 + version: 0.4.26(eslint@9.39.4) + globals: + specifier: ^15.14.0 + version: 15.15.0 + jsdom: + specifier: ^26.0.0 + version: 26.1.0 + prettier: + specifier: ^3.3.3 + version: 3.8.1 + typescript: + specifier: ~5.6.2 + version: 5.6.3 + typescript-eslint: + specifier: ^8.18.2 + version: 8.57.2(eslint@9.39.4)(typescript@5.6.3) + vite: + specifier: ^7.1.5 + version: 7.3.1 + vitest: + specifier: 3.2.4 + version: 3.2.4(jsdom@26.1.0) + +packages: + + '@adobe/css-tools@4.4.4': + resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} + + '@asamuzakjp/css-color@3.2.0': + resolution: {integrity: sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==} + + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@csstools/color-helpers@5.1.0': + resolution: {integrity: sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==} + engines: {node: '>=18'} + + '@csstools/css-calc@2.1.4': + resolution: {integrity: sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-color-parser@3.1.0': + resolution: {integrity: sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.5 + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-parser-algorithms@3.0.5': + resolution: {integrity: sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.4 + + '@csstools/css-tokenizer@3.0.4': + resolution: {integrity: sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==} + engines: {node: '>=18'} + + '@esbuild/aix-ppc64@0.27.4': + resolution: {integrity: sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.4': + resolution: {integrity: sha512-gdLscB7v75wRfu7QSm/zg6Rx29VLdy9eTr2t44sfTW7CxwAtQghZ4ZnqHk3/ogz7xao0QAgrkradbBzcqFPasw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.4': + resolution: {integrity: sha512-X9bUgvxiC8CHAGKYufLIHGXPJWnr0OCdR0anD2e21vdvgCI8lIfqFbnoeOz7lBjdrAGUhqLZLcQo6MLhTO2DKQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.4': + resolution: {integrity: sha512-PzPFnBNVF292sfpfhiyiXCGSn9HZg5BcAz+ivBuSsl6Rk4ga1oEXAamhOXRFyMcjwr2DVtm40G65N3GLeH1Lvw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.4': + resolution: {integrity: sha512-b7xaGIwdJlht8ZFCvMkpDN6uiSmnxxK56N2GDTMYPr2/gzvfdQN8rTfBsvVKmIVY/X7EM+/hJKEIbbHs9oA4tQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.4': + resolution: {integrity: sha512-sR+OiKLwd15nmCdqpXMnuJ9W2kpy0KigzqScqHI3Hqwr7IXxBp3Yva+yJwoqh7rE8V77tdoheRYataNKL4QrPw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.4': + resolution: {integrity: sha512-jnfpKe+p79tCnm4GVav68A7tUFeKQwQyLgESwEAUzyxk/TJr4QdGog9sqWNcUbr/bZt/O/HXouspuQDd9JxFSw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.4': + resolution: {integrity: sha512-2kb4ceA/CpfUrIcTUl1wrP/9ad9Atrp5J94Lq69w7UwOMolPIGrfLSvAKJp0RTvkPPyn6CIWrNy13kyLikZRZQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.4': + resolution: {integrity: sha512-7nQOttdzVGth1iz57kxg9uCz57dxQLHWxopL6mYuYthohPKEK0vU0C3O21CcBK6KDlkYVcnDXY099HcCDXd9dA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.4': + resolution: {integrity: sha512-aBYgcIxX/wd5n2ys0yESGeYMGF+pv6g0DhZr3G1ZG4jMfruU9Tl1i2Z+Wnj9/KjGz1lTLCcorqE2viePZqj4Eg==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.4': + resolution: {integrity: sha512-oPtixtAIzgvzYcKBQM/qZ3R+9TEUd1aNJQu0HhGyqtx6oS7qTpvjheIWBbes4+qu1bNlo2V4cbkISr8q6gRBFA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.4': + resolution: {integrity: sha512-8mL/vh8qeCoRcFH2nM8wm5uJP+ZcVYGGayMavi8GmRJjuI3g1v6Z7Ni0JJKAJW+m0EtUuARb6Lmp4hMjzCBWzA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.4': + resolution: {integrity: sha512-1RdrWFFiiLIW7LQq9Q2NES+HiD4NyT8Itj9AUeCl0IVCA459WnPhREKgwrpaIfTOe+/2rdntisegiPWn/r/aAw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.4': + resolution: {integrity: sha512-tLCwNG47l3sd9lpfyx9LAGEGItCUeRCWeAx6x2Jmbav65nAwoPXfewtAdtbtit/pJFLUWOhpv0FpS6GQAmPrHA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.4': + resolution: {integrity: sha512-BnASypppbUWyqjd1KIpU4AUBiIhVr6YlHx/cnPgqEkNoVOhHg+YiSVxM1RLfiy4t9cAulbRGTNCKOcqHrEQLIw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.4': + resolution: {integrity: sha512-+eUqgb/Z7vxVLezG8bVB9SfBie89gMueS+I0xYh2tJdw3vqA/0ImZJ2ROeWwVJN59ihBeZ7Tu92dF/5dy5FttA==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.4': + resolution: {integrity: sha512-S5qOXrKV8BQEzJPVxAwnryi2+Iq5pB40gTEIT69BQONqR7JH1EPIcQ/Uiv9mCnn05jff9umq/5nqzxlqTOg9NA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.4': + resolution: {integrity: sha512-xHT8X4sb0GS8qTqiwzHqpY00C95DPAq7nAwX35Ie/s+LO9830hrMd3oX0ZMKLvy7vsonee73x0lmcdOVXFzd6Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.4': + resolution: {integrity: sha512-RugOvOdXfdyi5Tyv40kgQnI0byv66BFgAqjdgtAKqHoZTbTF2QqfQrFwa7cHEORJf6X2ht+l9ABLMP0dnKYsgg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.4': + resolution: {integrity: sha512-2MyL3IAaTX+1/qP0O1SwskwcwCoOI4kV2IBX1xYnDDqthmq5ArrW94qSIKCAuRraMgPOmG0RDTA74mzYNQA9ow==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.4': + resolution: {integrity: sha512-u8fg/jQ5aQDfsnIV6+KwLOf1CmJnfu1ShpwqdwC0uA7ZPwFws55Ngc12vBdeUdnuWoQYx/SOQLGDcdlfXhYmXQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.4': + resolution: {integrity: sha512-JkTZrl6VbyO8lDQO3yv26nNr2RM2yZzNrNHEsj9bm6dOwwu9OYN28CjzZkH57bh4w0I2F7IodpQvUAEd1mbWXg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.4': + resolution: {integrity: sha512-/gOzgaewZJfeJTlsWhvUEmUG4tWEY2Spp5M20INYRg2ZKl9QPO3QEEgPeRtLjEWSW8FilRNacPOg8R1uaYkA6g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.4': + resolution: {integrity: sha512-Z9SExBg2y32smoDQdf1HRwHRt6vAHLXcxD2uGgO/v2jK7Y718Ix4ndsbNMU/+1Qiem9OiOdaqitioZwxivhXYg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.4': + resolution: {integrity: sha512-DAyGLS0Jz5G5iixEbMHi5KdiApqHBWMGzTtMiJ72ZOLhbu/bzxgAe8Ue8CTS3n3HbIUHQz/L51yMdGMeoxXNJw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.4': + resolution: {integrity: sha512-+knoa0BDoeXgkNvvV1vvbZX4+hizelrkwmGJBdT17t8FNPwG2lKemmuMZlmaNQ3ws3DKKCxpb4zRZEIp3UxFCg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.4': + resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@rolldown/pluginutils@1.0.0-rc.3': + resolution: {integrity: sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==} + + '@rollup/rollup-android-arm-eabi@4.60.0': + resolution: {integrity: sha512-WOhNW9K8bR3kf4zLxbfg6Pxu2ybOUbB2AjMDHSQx86LIF4rH4Ft7vmMwNt0loO0eonglSNy4cpD3MKXXKQu0/A==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.60.0': + resolution: {integrity: sha512-u6JHLll5QKRvjciE78bQXDmqRqNs5M/3GVqZeMwvmjaNODJih/WIrJlFVEihvV0MiYFmd+ZyPr9wxOVbPAG2Iw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.60.0': + resolution: {integrity: sha512-qEF7CsKKzSRc20Ciu2Zw1wRrBz4g56F7r/vRwY430UPp/nt1x21Q/fpJ9N5l47WWvJlkNCPJz3QRVw008fi7yA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.60.0': + resolution: {integrity: sha512-WADYozJ4QCnXCH4wPB+3FuGmDPoFseVCUrANmA5LWwGmC6FL14BWC7pcq+FstOZv3baGX65tZ378uT6WG8ynTw==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.60.0': + resolution: {integrity: sha512-6b8wGHJlDrGeSE3aH5mGNHBjA0TTkxdoNHik5EkvPHCt351XnigA4pS7Wsj/Eo9Y8RBU6f35cjN9SYmCFBtzxw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.60.0': + resolution: {integrity: sha512-h25Ga0t4jaylMB8M/JKAyrvvfxGRjnPQIR8lnCayyzEjEOx2EJIlIiMbhpWxDRKGKF8jbNH01NnN663dH638mA==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.60.0': + resolution: {integrity: sha512-RzeBwv0B3qtVBWtcuABtSuCzToo2IEAIQrcyB/b2zMvBWVbjo8bZDjACUpnaafaxhTw2W+imQbP2BD1usasK4g==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.60.0': + resolution: {integrity: sha512-Sf7zusNI2CIU1HLzuu9Tc5YGAHEZs5Lu7N1ssJG4Tkw6e0MEsN7NdjUDDfGNHy2IU+ENyWT+L2obgWiguWibWQ==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.60.0': + resolution: {integrity: sha512-DX2x7CMcrJzsE91q7/O02IJQ5/aLkVtYFryqCjduJhUfGKG6yJV8hxaw8pZa93lLEpPTP/ohdN4wFz7yp/ry9A==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.60.0': + resolution: {integrity: sha512-09EL+yFVbJZlhcQfShpswwRZ0Rg+z/CsSELFCnPt3iK+iqwGsI4zht3secj5vLEs957QvFFXnzAT0FFPIxSrkQ==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.60.0': + resolution: {integrity: sha512-i9IcCMPr3EXm8EQg5jnja0Zyc1iFxJjZWlb4wr7U2Wx/GrddOuEafxRdMPRYVaXjgbhvqalp6np07hN1w9kAKw==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-loong64-musl@4.60.0': + resolution: {integrity: sha512-DGzdJK9kyJ+B78MCkWeGnpXJ91tK/iKA6HwHxF4TAlPIY7GXEvMe8hBFRgdrR9Ly4qebR/7gfUs9y2IoaVEyog==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.60.0': + resolution: {integrity: sha512-RwpnLsqC8qbS8z1H1AxBA1H6qknR4YpPR9w2XX0vo2Sz10miu57PkNcnHVaZkbqyw/kUWfKMI73jhmfi9BRMUQ==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-musl@4.60.0': + resolution: {integrity: sha512-Z8pPf54Ly3aqtdWC3G4rFigZgNvd+qJlOE52fmko3KST9SoGfAdSRCwyoyG05q1HrrAblLbk1/PSIV+80/pxLg==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.60.0': + resolution: {integrity: sha512-3a3qQustp3COCGvnP4SvrMHnPQ9d1vzCakQVRTliaz8cIp/wULGjiGpbcqrkv0WrHTEp8bQD/B3HBjzujVWLOA==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.60.0': + resolution: {integrity: sha512-pjZDsVH/1VsghMJ2/kAaxt6dL0psT6ZexQVrijczOf+PeP2BUqTHYejk3l6TlPRydggINOeNRhvpLa0AYpCWSQ==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.60.0': + resolution: {integrity: sha512-3ObQs0BhvPgiUVZrN7gqCSvmFuMWvWvsjG5ayJ3Lraqv+2KhOsp+pUbigqbeWqueGIsnn+09HBw27rJ+gYK4VQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.60.0': + resolution: {integrity: sha512-EtylprDtQPdS5rXvAayrNDYoJhIz1/vzN2fEubo3yLE7tfAw+948dO0g4M0vkTVFhKojnF+n6C8bDNe+gDRdTg==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.60.0': + resolution: {integrity: sha512-k09oiRCi/bHU9UVFqD17r3eJR9bn03TyKraCrlz5ULFJGdJGi7VOmm9jl44vOJvRJ6P7WuBi/s2A97LxxHGIdw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.60.0': + resolution: {integrity: sha512-1o/0/pIhozoSaDJoDcec+IVLbnRtQmHwPV730+AOD29lHEEo4F5BEUB24H0OBdhbBBDwIOSuf7vgg0Ywxdfiiw==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.60.0': + resolution: {integrity: sha512-pESDkos/PDzYwtyzB5p/UoNU/8fJo68vcXM9ZW2V0kjYayj1KaaUfi1NmTUTUpMn4UhU4gTuK8gIaFO4UGuMbA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.60.0': + resolution: {integrity: sha512-hj1wFStD7B1YBeYmvY+lWXZ7ey73YGPcViMShYikqKT1GtstIKQAtfUI6yrzPjAy/O7pO0VLXGmUVWXQMaYgTQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.60.0': + resolution: {integrity: sha512-SyaIPFoxmUPlNDq5EHkTbiKzmSEmq/gOYFI/3HHJ8iS/v1mbugVa7dXUzcJGQfoytp9DJFLhHH4U3/eTy2Bq4w==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.60.0': + resolution: {integrity: sha512-RdcryEfzZr+lAr5kRm2ucN9aVlCCa2QNq4hXelZxb8GG0NJSazq44Z3PCCc8wISRuCVnGs0lQJVX5Vp6fKA+IA==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.60.0': + resolution: {integrity: sha512-PrsWNQ8BuE00O3Xsx3ALh2Df8fAj9+cvvX9AIA6o4KpATR98c9mud4XtDWVvsEuyia5U4tVSTKygawyJkjm60w==} + cpu: [x64] + os: [win32] + + '@testing-library/dom@10.4.1': + resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} + engines: {node: '>=18'} + + '@testing-library/jest-dom@6.9.1': + resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + + '@testing-library/react@16.3.2': + resolution: {integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==} + engines: {node: '>=18'} + peerDependencies: + '@testing-library/dom': ^10.0.0 + '@types/react': ^18.0.0 || ^19.0.0 + '@types/react-dom': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@testing-library/user-event@14.6.1': + resolution: {integrity: sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==} + engines: {node: '>=12', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/prop-types@15.7.15': + resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + + '@types/react-dom@18.3.7': + resolution: {integrity: sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==} + peerDependencies: + '@types/react': ^18.0.0 + + '@types/react@18.3.28': + resolution: {integrity: sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==} + + '@typescript-eslint/eslint-plugin@8.57.2': + resolution: {integrity: sha512-NZZgp0Fm2IkD+La5PR81sd+g+8oS6JwJje+aRWsDocxHkjyRw0J5L5ZTlN3LI1LlOcGL7ph3eaIUmTXMIjLk0w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.57.2 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/parser@8.57.2': + resolution: {integrity: sha512-30ScMRHIAD33JJQkgfGW1t8CURZtjc2JpTrq5n2HFhOefbAhb7ucc7xJwdWcrEtqUIYJ73Nybpsggii6GtAHjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/project-service@8.57.2': + resolution: {integrity: sha512-FuH0wipFywXRTHf+bTTjNyuNQQsQC3qh/dYzaM4I4W0jrCqjCVuUh99+xd9KamUfmCGPvbO8NDngo/vsnNVqgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/scope-manager@8.57.2': + resolution: {integrity: sha512-snZKH+W4WbWkrBqj4gUNRIGb/jipDW3qMqVJ4C9rzdFc+wLwruxk+2a5D+uoFcKPAqyqEnSb4l2ULuZf95eSkw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.57.2': + resolution: {integrity: sha512-3Lm5DSM+DCowsUOJC+YqHHnKEfFh5CoGkj5Z31NQSNF4l5wdOwqGn99wmwN/LImhfY3KJnmordBq/4+VDe2eKw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.57.2': + resolution: {integrity: sha512-Co6ZCShm6kIbAM/s+oYVpKFfW7LBc6FXoPXjTRQ449PPNBY8U0KZXuevz5IFuuUj2H9ss40atTaf9dlGLzbWZg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/types@8.57.2': + resolution: {integrity: sha512-/iZM6FnM4tnx9csuTxspMW4BOSegshwX5oBDznJ7S4WggL7Vczz5d2W11ecc4vRrQMQHXRSxzrCsyG5EsPPTbA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.57.2': + resolution: {integrity: sha512-2MKM+I6g8tJxfSmFKOnHv2t8Sk3T6rF20A1Puk0svLK+uVapDZB/4pfAeB7nE83uAZrU6OxW+HmOd5wHVdXwXA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/utils@8.57.2': + resolution: {integrity: sha512-krRIbvPK1ju1WBKIefiX+bngPs+odIQUtR7kymzPfo1POVw3jlF+nLkmexdSSd4UCbDcQn+wMBATOOmpBbqgKg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/visitor-keys@8.57.2': + resolution: {integrity: sha512-zhahknjobV2FiD6Ee9iLbS7OV9zi10rG26odsQdfBO/hjSzUQbkIYgda+iNKK1zNiW2ey+Lf8MU5btN17V3dUw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@vitejs/plugin-basic-ssl@2.3.0': + resolution: {integrity: sha512-bdyo8rB3NnQbikdMpHaML9Z1OZPBu6fFOBo+OtxsBlvMJtysWskmBcnbIDhUqgC8tcxNv/a+BcV5U+2nQMm1OQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + peerDependencies: + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@vitejs/plugin-react@5.2.0': + resolution: {integrity: sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@vitest/expect@3.2.4': + resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + + '@vitest/mocker@3.2.4': + resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + + '@vitest/runner@3.2.4': + resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} + + '@vitest/snapshot@3.2.4': + resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} + + '@vitest/spy@3.2.4': + resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + + '@vitest/utils@3.2.4': + resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ajv@6.14.0: + resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + baseline-browser-mapping@2.10.12: + resolution: {integrity: sha512-qyq26DxfY4awP2gIRXhhLWfwzwI+N5Nxk6iQi8EFizIaWIjqicQTE4sLnZZVdeKPRcVNoJOkkpfzoIYuvCKaIQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + brace-expansion@1.1.13: + resolution: {integrity: sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==} + + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + engines: {node: 18 || 20 || >=22} + + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001781: + resolution: {integrity: sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==} + + chai@5.3.3: + resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} + engines: {node: '>=18'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + check-error@2.1.3: + resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} + engines: {node: '>= 16'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + + cssstyle@4.6.0: + resolution: {integrity: sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==} + engines: {node: '>=18'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + data-urls@5.0.0: + resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} + engines: {node: '>=18'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + + dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + + electron-to-chromium@1.5.328: + resolution: {integrity: sha512-QNQ5l45DzYytThO21403XN3FvK0hOkWDG8viNf6jqS42msJ8I4tGDSpBCgvDRRPnkffafiwAym2X2eHeGD2V0w==} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + esbuild@0.27.4: + resolution: {integrity: sha512-Rq4vbHnYkK5fws5NF7MYTU68FPRE1ajX7heQ/8QXXWqNgqqJ/GkmmyxIzUnf2Sr/bakf8l54716CcMGHYhMrrQ==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-plugin-react-hooks@5.2.0: + resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react-refresh@0.4.26: + resolution: {integrity: sha512-1RETEylht2O6FM/MvgnyvT+8K21wLqDNg4qD51Zj3guhjt433XbnnkVttHMyaVyAFD03QSV4LPS5iE3VQmO7XQ==} + peerDependencies: + eslint: '>=8.40' + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@15.15.0: + resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} + engines: {node: '>=18'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + headers-polyfill@4.0.3: + resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} + + html-encoding-sniffer@4.0.0: + resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} + engines: {node: '>=18'} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsdom@26.1.0: + resolution: {integrity: sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==} + engines: {node: '>=18'} + peerDependencies: + canvas: ^3.0.0 + peerDependenciesMeta: + canvas: + optional: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jwt-decode@4.0.0: + resolution: {integrity: sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==} + engines: {node: '>=18'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + + minimatch@10.2.4: + resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + node-releases@2.0.36: + resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==} + + nwsapi@2.2.23: + resolution: {integrity: sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + oidc-client-ts@3.5.0: + resolution: {integrity: sha512-l2q8l9CTCTOlbX+AnK4p3M+4CEpKpyQhle6blQkdFhm0IsBqsxm15bYaSa11G7pWdsYr6epdsRZxJpCyCRbT8A==} + engines: {node: '>=18'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + pathval@2.0.1: + resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} + engines: {node: '>= 14.16'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} + engines: {node: '>=14'} + hasBin: true + + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pure-rand@7.0.1: + resolution: {integrity: sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==} + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + + react-oidc-context@3.3.1: + resolution: {integrity: sha512-/Azvm9W4DhhOtSDBE73kFInh1b6zZRRfILKbgmk2syExMF0PCYJOn/dGdOOi2BFX8x0rCeUe45NXHU+/+xDcrQ==} + engines: {node: '>=18'} + peerDependencies: + oidc-client-ts: ^3.1.0 + react: '>=16.14.0' + + react-refresh@0.18.0: + resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} + engines: {node: '>=0.10.0'} + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + rollup@4.60.0: + resolution: {integrity: sha512-yqjxruMGBQJ2gG4HtjZtAfXArHomazDHoFwFFmZZl0r7Pdo7qCIXKqKHZc8yeoMgzJJ+pO6pEEHa+V7uzWlrAQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + rrweb-cssom@0.8.0: + resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + spacetimedb@2.1.0: + resolution: {integrity: sha512-Kzs+HXCRj15ryld03ztU4a2uQg0M8ivV/9Bk/gvMpb59lLc/A2/r7UkGCYBePsBL7Zwqgr8gE8FeufoZVXtPnA==} + peerDependencies: + '@angular/core': '>=17.0.0' + '@tanstack/react-query': ^5.0.0 + react: ^18.0.0 || ^19.0.0-0 || ^19.0.0 + svelte: ^4.0.0 || ^5.0.0 + undici: ^6.19.2 + vue: ^3.3.0 + peerDependenciesMeta: + '@angular/core': + optional: true + '@tanstack/react-query': + optional: true + react: + optional: true + svelte: + optional: true + undici: + optional: true + vue: + optional: true + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strip-literal@3.1.0: + resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@2.0.0: + resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} + engines: {node: '>=14.0.0'} + + tinyspy@4.0.4: + resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} + engines: {node: '>=14.0.0'} + + tldts-core@6.1.86: + resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} + + tldts@6.1.86: + resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} + hasBin: true + + tough-cookie@5.1.2: + resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} + engines: {node: '>=16'} + + tr46@5.1.1: + resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==} + engines: {node: '>=18'} + + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typescript-eslint@8.57.2: + resolution: {integrity: sha512-VEPQ0iPgWO/sBaZOU1xo4nuNdODVOajPnTIbog2GKYr31nIlZ0fWPoCQgGfF3ETyBl1vn63F/p50Um9Z4J8O8A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.0.0' + + typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + engines: {node: '>=14.17'} + hasBin: true + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + url-polyfill@1.1.14: + resolution: {integrity: sha512-p4f3TTAG6ADVF3mwbXw7hGw+QJyw5CnNGvYh5fCuQQZIiuKUswqcznyV3pGDP9j0TSmC4UvRKm8kl1QsX1diiQ==} + + vite-node@3.2.4: + resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + + vite@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@3.2.4: + resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/debug': ^4.1.12 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@vitest/browser': 3.2.4 + '@vitest/ui': 3.2.4 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/debug': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + + whatwg-url@14.2.0: + resolution: {integrity: sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==} + engines: {node: '>=18'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + ws@8.20.0: + resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@adobe/css-tools@4.4.4': {} + + '@asamuzakjp/css-color@3.2.0': + dependencies: + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + lru-cache: 10.4.3 + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.0': {} + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.1 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.28.6': {} + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.29.2': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/parser@7.29.2': + dependencies: + '@babel/types': 7.29.0 + + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/runtime@7.29.2': {} + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@csstools/color-helpers@5.1.0': {} + + '@csstools/css-calc@2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-color-parser@3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/color-helpers': 5.1.0 + '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) + '@csstools/css-parser-algorithms': 3.0.5(@csstools/css-tokenizer@3.0.4) + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4)': + dependencies: + '@csstools/css-tokenizer': 3.0.4 + + '@csstools/css-tokenizer@3.0.4': {} + + '@esbuild/aix-ppc64@0.27.4': + optional: true + + '@esbuild/android-arm64@0.27.4': + optional: true + + '@esbuild/android-arm@0.27.4': + optional: true + + '@esbuild/android-x64@0.27.4': + optional: true + + '@esbuild/darwin-arm64@0.27.4': + optional: true + + '@esbuild/darwin-x64@0.27.4': + optional: true + + '@esbuild/freebsd-arm64@0.27.4': + optional: true + + '@esbuild/freebsd-x64@0.27.4': + optional: true + + '@esbuild/linux-arm64@0.27.4': + optional: true + + '@esbuild/linux-arm@0.27.4': + optional: true + + '@esbuild/linux-ia32@0.27.4': + optional: true + + '@esbuild/linux-loong64@0.27.4': + optional: true + + '@esbuild/linux-mips64el@0.27.4': + optional: true + + '@esbuild/linux-ppc64@0.27.4': + optional: true + + '@esbuild/linux-riscv64@0.27.4': + optional: true + + '@esbuild/linux-s390x@0.27.4': + optional: true + + '@esbuild/linux-x64@0.27.4': + optional: true + + '@esbuild/netbsd-arm64@0.27.4': + optional: true + + '@esbuild/netbsd-x64@0.27.4': + optional: true + + '@esbuild/openbsd-arm64@0.27.4': + optional: true + + '@esbuild/openbsd-x64@0.27.4': + optional: true + + '@esbuild/openharmony-arm64@0.27.4': + optional: true + + '@esbuild/sunos-x64@0.27.4': + optional: true + + '@esbuild/win32-arm64@0.27.4': + optional: true + + '@esbuild/win32-ia32@0.27.4': + optional: true + + '@esbuild/win32-x64@0.27.4': + optional: true + + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4)': + dependencies: + eslint: 9.39.4 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.2': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.5': + dependencies: + ajv: 6.14.0 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.4': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.7': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.4.3 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@rolldown/pluginutils@1.0.0-rc.3': {} + + '@rollup/rollup-android-arm-eabi@4.60.0': + optional: true + + '@rollup/rollup-android-arm64@4.60.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.60.0': + optional: true + + '@rollup/rollup-darwin-x64@4.60.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.60.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.60.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.60.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.60.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.60.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.60.0': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.60.0': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.60.0': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.60.0': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.60.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.60.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.60.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.60.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.60.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.60.0': + optional: true + + '@rollup/rollup-openbsd-x64@4.60.0': + optional: true + + '@rollup/rollup-openharmony-arm64@4.60.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.60.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.60.0': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.60.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.60.0': + optional: true + + '@testing-library/dom@10.4.1': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/runtime': 7.29.2 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + picocolors: 1.1.1 + pretty-format: 27.5.1 + + '@testing-library/jest-dom@6.9.1': + dependencies: + '@adobe/css-tools': 4.4.4 + aria-query: 5.3.2 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + picocolors: 1.1.1 + redent: 3.0.0 + + '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@18.3.7(@types/react@18.3.28))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.29.2 + '@testing-library/dom': 10.4.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.28 + '@types/react-dom': 18.3.7(@types/react@18.3.28) + + '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)': + dependencies: + '@testing-library/dom': 10.4.1 + + '@types/aria-query@5.0.4': {} + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.29.0 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.29.0 + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/deep-eql@4.0.2': {} + + '@types/estree@1.0.8': {} + + '@types/json-schema@7.0.15': {} + + '@types/prop-types@15.7.15': {} + + '@types/react-dom@18.3.7(@types/react@18.3.28)': + dependencies: + '@types/react': 18.3.28 + + '@types/react@18.3.28': + dependencies: + '@types/prop-types': 15.7.15 + csstype: 3.2.3 + + '@typescript-eslint/eslint-plugin@8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4)(typescript@5.6.3))(eslint@9.39.4)(typescript@5.6.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.57.2(eslint@9.39.4)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/type-utils': 8.57.2(eslint@9.39.4)(typescript@5.6.3) + '@typescript-eslint/utils': 8.57.2(eslint@9.39.4)(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.57.2 + eslint: 9.39.4 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.57.2(eslint@9.39.4)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.57.2 + debug: 4.4.3 + eslint: 9.39.4 + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.57.2(typescript@5.6.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.57.2(typescript@5.6.3) + '@typescript-eslint/types': 8.57.2 + debug: 4.4.3 + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.57.2': + dependencies: + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/visitor-keys': 8.57.2 + + '@typescript-eslint/tsconfig-utils@8.57.2(typescript@5.6.3)': + dependencies: + typescript: 5.6.3 + + '@typescript-eslint/type-utils@8.57.2(eslint@9.39.4)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.6.3) + '@typescript-eslint/utils': 8.57.2(eslint@9.39.4)(typescript@5.6.3) + debug: 4.4.3 + eslint: 9.39.4 + ts-api-utils: 2.5.0(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.57.2': {} + + '@typescript-eslint/typescript-estree@8.57.2(typescript@5.6.3)': + dependencies: + '@typescript-eslint/project-service': 8.57.2(typescript@5.6.3) + '@typescript-eslint/tsconfig-utils': 8.57.2(typescript@5.6.3) + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/visitor-keys': 8.57.2 + debug: 4.4.3 + minimatch: 10.2.4 + semver: 7.7.4 + tinyglobby: 0.2.15 + ts-api-utils: 2.5.0(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.57.2(eslint@9.39.4)(typescript@5.6.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@typescript-eslint/scope-manager': 8.57.2 + '@typescript-eslint/types': 8.57.2 + '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.6.3) + eslint: 9.39.4 + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.57.2': + dependencies: + '@typescript-eslint/types': 8.57.2 + eslint-visitor-keys: 5.0.1 + + '@vitejs/plugin-basic-ssl@2.3.0(vite@7.3.1)': + dependencies: + vite: 7.3.1 + + '@vitejs/plugin-react@5.2.0(vite@7.3.1)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.29.0) + '@rolldown/pluginutils': 1.0.0-rc.3 + '@types/babel__core': 7.20.5 + react-refresh: 0.18.0 + vite: 7.3.1 + transitivePeerDependencies: + - supports-color + + '@vitest/expect@3.2.4': + dependencies: + '@types/chai': 5.2.3 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.3.3 + tinyrainbow: 2.0.0 + + '@vitest/mocker@3.2.4(vite@7.3.1)': + dependencies: + '@vitest/spy': 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 7.3.1 + + '@vitest/pretty-format@3.2.4': + dependencies: + tinyrainbow: 2.0.0 + + '@vitest/runner@3.2.4': + dependencies: + '@vitest/utils': 3.2.4 + pathe: 2.0.3 + strip-literal: 3.1.0 + + '@vitest/snapshot@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@3.2.4': + dependencies: + tinyspy: 4.0.4 + + '@vitest/utils@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + loupe: 3.2.1 + tinyrainbow: 2.0.0 + + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + agent-base@7.1.4: {} + + ajv@6.14.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + argparse@2.0.1: {} + + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + + aria-query@5.3.2: {} + + assertion-error@2.0.1: {} + + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + + base64-js@1.5.1: {} + + baseline-browser-mapping@2.10.12: {} + + brace-expansion@1.1.13: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@5.0.5: + dependencies: + balanced-match: 4.0.4 + + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.10.12 + caniuse-lite: 1.0.30001781 + electron-to-chromium: 1.5.328 + node-releases: 2.0.36 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + + cac@6.7.14: {} + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001781: {} + + chai@5.3.3: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.3 + deep-eql: 5.0.2 + loupe: 3.2.1 + pathval: 2.0.1 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + check-error@2.1.3: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + concat-map@0.0.1: {} + + convert-source-map@2.0.0: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + css.escape@1.5.1: {} + + cssstyle@4.6.0: + dependencies: + '@asamuzakjp/css-color': 3.2.0 + rrweb-cssom: 0.8.0 + + csstype@3.2.3: {} + + data-urls@5.0.0: + dependencies: + whatwg-mimetype: 4.0.0 + whatwg-url: 14.2.0 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decimal.js@10.6.0: {} + + deep-eql@5.0.2: {} + + deep-is@0.1.4: {} + + dequal@2.0.3: {} + + dom-accessibility-api@0.5.16: {} + + dom-accessibility-api@0.6.3: {} + + electron-to-chromium@1.5.328: {} + + entities@6.0.1: {} + + es-module-lexer@1.7.0: {} + + esbuild@0.27.4: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.4 + '@esbuild/android-arm': 0.27.4 + '@esbuild/android-arm64': 0.27.4 + '@esbuild/android-x64': 0.27.4 + '@esbuild/darwin-arm64': 0.27.4 + '@esbuild/darwin-x64': 0.27.4 + '@esbuild/freebsd-arm64': 0.27.4 + '@esbuild/freebsd-x64': 0.27.4 + '@esbuild/linux-arm': 0.27.4 + '@esbuild/linux-arm64': 0.27.4 + '@esbuild/linux-ia32': 0.27.4 + '@esbuild/linux-loong64': 0.27.4 + '@esbuild/linux-mips64el': 0.27.4 + '@esbuild/linux-ppc64': 0.27.4 + '@esbuild/linux-riscv64': 0.27.4 + '@esbuild/linux-s390x': 0.27.4 + '@esbuild/linux-x64': 0.27.4 + '@esbuild/netbsd-arm64': 0.27.4 + '@esbuild/netbsd-x64': 0.27.4 + '@esbuild/openbsd-arm64': 0.27.4 + '@esbuild/openbsd-x64': 0.27.4 + '@esbuild/openharmony-arm64': 0.27.4 + '@esbuild/sunos-x64': 0.27.4 + '@esbuild/win32-arm64': 0.27.4 + '@esbuild/win32-ia32': 0.27.4 + '@esbuild/win32-x64': 0.27.4 + + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-plugin-react-hooks@5.2.0(eslint@9.39.4): + dependencies: + eslint: 9.39.4 + + eslint-plugin-react-refresh@0.4.26(eslint@9.39.4): + dependencies: + eslint: 9.39.4 + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@9.39.4: + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.2 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.14.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 4.2.1 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + esutils@2.0.3: {} + + expect-type@1.3.0: {} + + fast-deep-equal@3.1.3: {} + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + + flatted@3.4.2: {} + + fsevents@2.3.3: + optional: true + + gensync@1.0.0-beta.2: {} + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@14.0.0: {} + + globals@15.15.0: {} + + has-flag@4.0.0: {} + + headers-polyfill@4.0.3: {} + + html-encoding-sniffer@4.0.0: + dependencies: + whatwg-encoding: 3.1.1 + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-potential-custom-element-name@1.0.1: {} + + isexe@2.0.0: {} + + js-tokens@4.0.0: {} + + js-tokens@9.0.1: {} + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsdom@26.1.0: + dependencies: + cssstyle: 4.6.0 + data-urls: 5.0.0 + decimal.js: 10.6.0 + html-encoding-sniffer: 4.0.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.23 + parse5: 7.3.0 + rrweb-cssom: 0.8.0 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 5.1.2 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 3.1.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.2.0 + ws: 8.20.0 + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + + jwt-decode@4.0.0: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + loupe@3.2.1: {} + + lru-cache@10.4.3: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lz-string@1.5.0: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + min-indent@1.0.1: {} + + minimatch@10.2.4: + dependencies: + brace-expansion: 5.0.5 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.13 + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + natural-compare@1.4.0: {} + + node-releases@2.0.36: {} + + nwsapi@2.2.23: {} + + object-inspect@1.13.4: {} + + oidc-client-ts@3.5.0: + dependencies: + jwt-decode: 4.0.0 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + pathe@2.0.3: {} + + pathval@2.0.1: {} + + picocolors@1.1.1: {} + + picomatch@4.0.4: {} + + postcss@8.5.8: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier@3.8.1: {} + + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + + punycode@2.3.1: {} + + pure-rand@7.0.1: {} + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-is@17.0.2: {} + + react-oidc-context@3.3.1(oidc-client-ts@3.5.0)(react@18.3.1): + dependencies: + oidc-client-ts: 3.5.0 + react: 18.3.1 + + react-refresh@0.18.0: {} + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + redent@3.0.0: + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + + resolve-from@4.0.0: {} + + rollup@4.60.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.60.0 + '@rollup/rollup-android-arm64': 4.60.0 + '@rollup/rollup-darwin-arm64': 4.60.0 + '@rollup/rollup-darwin-x64': 4.60.0 + '@rollup/rollup-freebsd-arm64': 4.60.0 + '@rollup/rollup-freebsd-x64': 4.60.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.0 + '@rollup/rollup-linux-arm-musleabihf': 4.60.0 + '@rollup/rollup-linux-arm64-gnu': 4.60.0 + '@rollup/rollup-linux-arm64-musl': 4.60.0 + '@rollup/rollup-linux-loong64-gnu': 4.60.0 + '@rollup/rollup-linux-loong64-musl': 4.60.0 + '@rollup/rollup-linux-ppc64-gnu': 4.60.0 + '@rollup/rollup-linux-ppc64-musl': 4.60.0 + '@rollup/rollup-linux-riscv64-gnu': 4.60.0 + '@rollup/rollup-linux-riscv64-musl': 4.60.0 + '@rollup/rollup-linux-s390x-gnu': 4.60.0 + '@rollup/rollup-linux-x64-gnu': 4.60.0 + '@rollup/rollup-linux-x64-musl': 4.60.0 + '@rollup/rollup-openbsd-x64': 4.60.0 + '@rollup/rollup-openharmony-arm64': 4.60.0 + '@rollup/rollup-win32-arm64-msvc': 4.60.0 + '@rollup/rollup-win32-ia32-msvc': 4.60.0 + '@rollup/rollup-win32-x64-gnu': 4.60.0 + '@rollup/rollup-win32-x64-msvc': 4.60.0 + fsevents: 2.3.3 + + rrweb-cssom@0.8.0: {} + + safe-stable-stringify@2.5.0: {} + + safer-buffer@2.1.2: {} + + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + semver@6.3.1: {} + + semver@7.7.4: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + siginfo@2.0.0: {} + + source-map-js@1.2.1: {} + + spacetimedb@2.1.0(react@18.3.1): + dependencies: + base64-js: 1.5.1 + headers-polyfill: 4.0.3 + object-inspect: 1.13.4 + prettier: 3.8.1 + pure-rand: 7.0.1 + safe-stable-stringify: 2.5.0 + statuses: 2.0.2 + url-polyfill: 1.1.14 + optionalDependencies: + react: 18.3.1 + + stackback@0.0.2: {} + + statuses@2.0.2: {} + + std-env@3.10.0: {} + + strip-indent@3.0.0: + dependencies: + min-indent: 1.0.1 + + strip-json-comments@3.1.1: {} + + strip-literal@3.1.0: + dependencies: + js-tokens: 9.0.1 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + symbol-tree@3.2.4: {} + + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + + tinypool@1.1.1: {} + + tinyrainbow@2.0.0: {} + + tinyspy@4.0.4: {} + + tldts-core@6.1.86: {} + + tldts@6.1.86: + dependencies: + tldts-core: 6.1.86 + + tough-cookie@5.1.2: + dependencies: + tldts: 6.1.86 + + tr46@5.1.1: + dependencies: + punycode: 2.3.1 + + ts-api-utils@2.5.0(typescript@5.6.3): + dependencies: + typescript: 5.6.3 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typescript-eslint@8.57.2(eslint@9.39.4)(typescript@5.6.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.57.2(@typescript-eslint/parser@8.57.2(eslint@9.39.4)(typescript@5.6.3))(eslint@9.39.4)(typescript@5.6.3) + '@typescript-eslint/parser': 8.57.2(eslint@9.39.4)(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 8.57.2(typescript@5.6.3) + '@typescript-eslint/utils': 8.57.2(eslint@9.39.4)(typescript@5.6.3) + eslint: 9.39.4 + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + typescript@5.6.3: {} + + update-browserslist-db@1.2.3(browserslist@4.28.1): + dependencies: + browserslist: 4.28.1 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + url-polyfill@1.1.14: {} + + vite-node@3.2.4: + dependencies: + cac: 6.7.14 + debug: 4.4.3 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 7.3.1 + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vite@7.3.1: + dependencies: + esbuild: 0.27.4 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + postcss: 8.5.8 + rollup: 4.60.0 + tinyglobby: 0.2.15 + optionalDependencies: + fsevents: 2.3.3 + + vitest@3.2.4(jsdom@26.1.0): + dependencies: + '@types/chai': 5.2.3 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(vite@7.3.1) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 3.2.4 + '@vitest/snapshot': 3.2.4 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.3.3 + debug: 4.4.3 + expect-type: 1.3.0 + magic-string: 0.30.21 + pathe: 2.0.3 + picomatch: 4.0.4 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.15 + tinypool: 1.1.1 + tinyrainbow: 2.0.0 + vite: 7.3.1 + vite-node: 3.2.4 + why-is-node-running: 2.3.0 + optionalDependencies: + jsdom: 26.1.0 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + w3c-xmlserializer@5.0.0: + dependencies: + xml-name-validator: 5.0.0 + + webidl-conversions@7.0.0: {} + + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@4.0.0: {} + + whatwg-url@14.2.0: + dependencies: + tr46: 5.1.1 + webidl-conversions: 7.0.0 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + word-wrap@1.2.5: {} + + ws@8.20.0: {} + + xml-name-validator@5.0.0: {} + + xmlchars@2.2.0: {} + + yallist@3.1.1: {} + + yocto-queue@0.1.0: {} diff --git a/public/vite.svg b/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/spacetime.json b/spacetime.json new file mode 100644 index 0000000..e5af965 --- /dev/null +++ b/spacetime.json @@ -0,0 +1,8 @@ +{ + "dev": { + "run": "pnpm run dev" + }, + "server": "maincloud", + "database": "my-spacetime-app-jdhdg", + "module-path": "./spacetimedb" +} \ No newline at end of file diff --git a/spacetime.local.json b/spacetime.local.json new file mode 100644 index 0000000..c174128 --- /dev/null +++ b/spacetime.local.json @@ -0,0 +1,3 @@ +{ + "database": "my-spacetime-app-jdhdg" +} \ No newline at end of file diff --git a/spacetimedb/dist/bundle.js b/spacetimedb/dist/bundle.js new file mode 100644 index 0000000..96a2849 --- /dev/null +++ b/spacetimedb/dist/bundle.js @@ -0,0 +1,6385 @@ +import * as _syscalls2_0 from "spacetime:sys@2.0"; +import { moduleHooks } from "spacetime:sys@2.0"; + +//#region node_modules/.pnpm/headers-polyfill@4.0.3/node_modules/headers-polyfill/lib/index.mjs +var __create$1 = Object.create; +var __defProp$1 = Object.defineProperty; +var __getOwnPropDesc$1 = Object.getOwnPropertyDescriptor; +var __getOwnPropNames$1 = Object.getOwnPropertyNames; +var __getProtoOf$1 = Object.getPrototypeOf; +var __hasOwnProp$1 = Object.prototype.hasOwnProperty; +var __commonJS$1 = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames$1(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __copyProps$1 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames$1(from)) if (!__hasOwnProp$1.call(to, key) && key !== except) __defProp$1(to, key, { + get: () => from[key], + enumerable: !(desc = __getOwnPropDesc$1(from, key)) || desc.enumerable + }); + } + return to; +}; +var __toESM$1 = (mod, isNodeMode, target) => (target = mod != null ? __create$1(__getProtoOf$1(mod)) : {}, __copyProps$1(isNodeMode || !mod || !mod.__esModule ? __defProp$1(target, "default", { + value: mod, + enumerable: true +}) : target, mod)); +var import_set_cookie_parser = __toESM$1(__commonJS$1({ "node_modules/set-cookie-parser/lib/set-cookie.js"(exports, module) { + "use strict"; + var defaultParseOptions = { + decodeValues: true, + map: false, + silent: false + }; + function isNonEmptyString(str) { + return typeof str === "string" && !!str.trim(); + } + function parseString(setCookieValue, options) { + var parts = setCookieValue.split(";").filter(isNonEmptyString); + var parsed = parseNameValuePair(parts.shift()); + var name = parsed.name; + var value = parsed.value; + options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions; + try { + value = options.decodeValues ? decodeURIComponent(value) : value; + } catch (e) { + console.error("set-cookie-parser encountered an error while decoding a cookie with value '" + value + "'. Set options.decodeValues to false to disable this feature.", e); + } + var cookie = { + name, + value + }; + parts.forEach(function(part) { + var sides = part.split("="); + var key = sides.shift().trimLeft().toLowerCase(); + var value2 = sides.join("="); + if (key === "expires") cookie.expires = new Date(value2); + else if (key === "max-age") cookie.maxAge = parseInt(value2, 10); + else if (key === "secure") cookie.secure = true; + else if (key === "httponly") cookie.httpOnly = true; + else if (key === "samesite") cookie.sameSite = value2; + else cookie[key] = value2; + }); + return cookie; + } + function parseNameValuePair(nameValuePairStr) { + var name = ""; + var value = ""; + var nameValueArr = nameValuePairStr.split("="); + if (nameValueArr.length > 1) { + name = nameValueArr.shift(); + value = nameValueArr.join("="); + } else value = nameValuePairStr; + return { + name, + value + }; + } + function parse(input, options) { + options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions; + if (!input) if (!options.map) return []; + else return {}; + if (input.headers) if (typeof input.headers.getSetCookie === "function") input = input.headers.getSetCookie(); + else if (input.headers["set-cookie"]) input = input.headers["set-cookie"]; + else { + var sch = input.headers[Object.keys(input.headers).find(function(key) { + return key.toLowerCase() === "set-cookie"; + })]; + if (!sch && input.headers.cookie && !options.silent) console.warn("Warning: set-cookie-parser appears to have been called on a request object. It is designed to parse Set-Cookie headers from responses, not Cookie headers from requests. Set the option {silent: true} to suppress this warning."); + input = sch; + } + if (!Array.isArray(input)) input = [input]; + options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions; + if (!options.map) return input.filter(isNonEmptyString).map(function(str) { + return parseString(str, options); + }); + else return input.filter(isNonEmptyString).reduce(function(cookies2, str) { + var cookie = parseString(str, options); + cookies2[cookie.name] = cookie; + return cookies2; + }, {}); + } + function splitCookiesString2(cookiesString) { + if (Array.isArray(cookiesString)) return cookiesString; + if (typeof cookiesString !== "string") return []; + var cookiesStrings = []; + var pos = 0; + var start; + var ch; + var lastComma; + var nextStart; + var cookiesSeparatorFound; + function skipWhitespace() { + while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos))) pos += 1; + return pos < cookiesString.length; + } + function notSpecialChar() { + ch = cookiesString.charAt(pos); + return ch !== "=" && ch !== ";" && ch !== ","; + } + while (pos < cookiesString.length) { + start = pos; + cookiesSeparatorFound = false; + while (skipWhitespace()) { + ch = cookiesString.charAt(pos); + if (ch === ",") { + lastComma = pos; + pos += 1; + skipWhitespace(); + nextStart = pos; + while (pos < cookiesString.length && notSpecialChar()) pos += 1; + if (pos < cookiesString.length && cookiesString.charAt(pos) === "=") { + cookiesSeparatorFound = true; + pos = nextStart; + cookiesStrings.push(cookiesString.substring(start, lastComma)); + start = pos; + } else pos = lastComma + 1; + } else pos += 1; + } + if (!cookiesSeparatorFound || pos >= cookiesString.length) cookiesStrings.push(cookiesString.substring(start, cookiesString.length)); + } + return cookiesStrings; + } + module.exports = parse; + module.exports.parse = parse; + module.exports.parseString = parseString; + module.exports.splitCookiesString = splitCookiesString2; +} })()); +var HEADERS_INVALID_CHARACTERS = /[^a-z0-9\-#$%&'*+.^_`|~]/i; +function normalizeHeaderName(name) { + if (HEADERS_INVALID_CHARACTERS.test(name) || name.trim() === "") throw new TypeError("Invalid character in header field name"); + return name.trim().toLowerCase(); +} +var charCodesToRemove = [ + String.fromCharCode(10), + String.fromCharCode(13), + String.fromCharCode(9), + String.fromCharCode(32) +]; +var HEADER_VALUE_REMOVE_REGEXP = new RegExp(`(^[${charCodesToRemove.join("")}]|$[${charCodesToRemove.join("")}])`, "g"); +function normalizeHeaderValue(value) { + return value.replace(HEADER_VALUE_REMOVE_REGEXP, ""); +} +function isValidHeaderName(value) { + if (typeof value !== "string") return false; + if (value.length === 0) return false; + for (let i = 0; i < value.length; i++) { + const character = value.charCodeAt(i); + if (character > 127 || !isToken(character)) return false; + } + return true; +} +function isToken(value) { + return ![ + 127, + 32, + "(", + ")", + "<", + ">", + "@", + ",", + ";", + ":", + "\\", + "\"", + "/", + "[", + "]", + "?", + "=", + "{", + "}" + ].includes(value); +} +function isValidHeaderValue(value) { + if (typeof value !== "string") return false; + if (value.trim() !== value) return false; + for (let i = 0; i < value.length; i++) { + const character = value.charCodeAt(i); + if (character === 0 || character === 10 || character === 13) return false; + } + return true; +} +var NORMALIZED_HEADERS = Symbol("normalizedHeaders"); +var RAW_HEADER_NAMES = Symbol("rawHeaderNames"); +var HEADER_VALUE_DELIMITER = ", "; +var _a, _b, _c; +var Headers = class _Headers { + constructor(init) { + this[_a] = {}; + this[_b] = /* @__PURE__ */ new Map(); + this[_c] = "Headers"; + if (["Headers", "HeadersPolyfill"].includes(init?.constructor.name) || init instanceof _Headers || typeof globalThis.Headers !== "undefined" && init instanceof globalThis.Headers) init.forEach((value, name) => { + this.append(name, value); + }, this); + else if (Array.isArray(init)) init.forEach(([name, value]) => { + this.append(name, Array.isArray(value) ? value.join(HEADER_VALUE_DELIMITER) : value); + }); + else if (init) Object.getOwnPropertyNames(init).forEach((name) => { + const value = init[name]; + this.append(name, Array.isArray(value) ? value.join(HEADER_VALUE_DELIMITER) : value); + }); + } + [(_a = NORMALIZED_HEADERS, _b = RAW_HEADER_NAMES, _c = Symbol.toStringTag, Symbol.iterator)]() { + return this.entries(); + } + *keys() { + for (const [name] of this.entries()) yield name; + } + *values() { + for (const [, value] of this.entries()) yield value; + } + *entries() { + let sortedKeys = Object.keys(this[NORMALIZED_HEADERS]).sort((a, b) => a.localeCompare(b)); + for (const name of sortedKeys) if (name === "set-cookie") for (const value of this.getSetCookie()) yield [name, value]; + else yield [name, this.get(name)]; + } + /** + * Returns a boolean stating whether a `Headers` object contains a certain header. + */ + has(name) { + if (!isValidHeaderName(name)) throw new TypeError(`Invalid header name "${name}"`); + return this[NORMALIZED_HEADERS].hasOwnProperty(normalizeHeaderName(name)); + } + /** + * Returns a `ByteString` sequence of all the values of a header with a given name. + */ + get(name) { + if (!isValidHeaderName(name)) throw TypeError(`Invalid header name "${name}"`); + return this[NORMALIZED_HEADERS][normalizeHeaderName(name)] ?? null; + } + /** + * Sets a new value for an existing header inside a `Headers` object, or adds the header if it does not already exist. + */ + set(name, value) { + if (!isValidHeaderName(name) || !isValidHeaderValue(value)) return; + const normalizedName = normalizeHeaderName(name); + const normalizedValue = normalizeHeaderValue(value); + this[NORMALIZED_HEADERS][normalizedName] = normalizeHeaderValue(normalizedValue); + this[RAW_HEADER_NAMES].set(normalizedName, name); + } + /** + * Appends a new value onto an existing header inside a `Headers` object, or adds the header if it does not already exist. + */ + append(name, value) { + if (!isValidHeaderName(name) || !isValidHeaderValue(value)) return; + const normalizedName = normalizeHeaderName(name); + const normalizedValue = normalizeHeaderValue(value); + let resolvedValue = this.has(normalizedName) ? `${this.get(normalizedName)}, ${normalizedValue}` : normalizedValue; + this.set(name, resolvedValue); + } + /** + * Deletes a header from the `Headers` object. + */ + delete(name) { + if (!isValidHeaderName(name)) return; + if (!this.has(name)) return; + const normalizedName = normalizeHeaderName(name); + delete this[NORMALIZED_HEADERS][normalizedName]; + this[RAW_HEADER_NAMES].delete(normalizedName); + } + /** + * Traverses the `Headers` object, + * calling the given callback for each header. + */ + forEach(callback, thisArg) { + for (const [name, value] of this.entries()) callback.call(thisArg, value, name, this); + } + /** + * Returns an array containing the values + * of all Set-Cookie headers associated + * with a response + */ + getSetCookie() { + const setCookieHeader = this.get("set-cookie"); + if (setCookieHeader === null) return []; + if (setCookieHeader === "") return [""]; + return (0, import_set_cookie_parser.splitCookiesString)(setCookieHeader); + } +}; +function headersToList(headers) { + const headersList = []; + headers.forEach((value, name) => { + const resolvedValue = value.includes(",") ? value.split(",").map((value2) => value2.trim()) : value; + headersList.push([name, resolvedValue]); + }); + return headersList; +} + +//#endregion +//#region node_modules/.pnpm/spacetimedb@2.1.0/node_modules/spacetimedb/dist/server/index.mjs +typeof globalThis !== "undefined" && (globalThis.global = globalThis.global || globalThis, globalThis.window = globalThis.window || globalThis); +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __esm = (fn, res) => function __init() { + return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; +}; +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __export = (target, all) => { + for (var name in all) __defProp(target, name, { + get: all[name], + enumerable: true + }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { + get: () => from[key], + enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable + }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(__defProp(target, "default", { + value: mod, + enumerable: true +}), mod)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); +var require_base64_js = __commonJS({ "../../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js"(exports) { + exports.byteLength = byteLength; + exports.toByteArray = toByteArray; + exports.fromByteArray = fromByteArray2; + var lookup = []; + var revLookup = []; + var Arr = typeof Uint8Array !== "undefined" ? Uint8Array : Array; + var code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + for (i = 0, len = code.length; i < len; ++i) { + lookup[i] = code[i]; + revLookup[code.charCodeAt(i)] = i; + } + var i; + var len; + revLookup["-".charCodeAt(0)] = 62; + revLookup["_".charCodeAt(0)] = 63; + function getLens(b64) { + var len2 = b64.length; + if (len2 % 4 > 0) throw new Error("Invalid string. Length must be a multiple of 4"); + var validLen = b64.indexOf("="); + if (validLen === -1) validLen = len2; + var placeHoldersLen = validLen === len2 ? 0 : 4 - validLen % 4; + return [validLen, placeHoldersLen]; + } + function byteLength(b64) { + var lens = getLens(b64); + var validLen = lens[0]; + var placeHoldersLen = lens[1]; + return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen; + } + function _byteLength(b64, validLen, placeHoldersLen) { + return (validLen + placeHoldersLen) * 3 / 4 - placeHoldersLen; + } + function toByteArray(b64) { + var tmp; + var lens = getLens(b64); + var validLen = lens[0]; + var placeHoldersLen = lens[1]; + var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen)); + var curByte = 0; + var len2 = placeHoldersLen > 0 ? validLen - 4 : validLen; + var i2; + for (i2 = 0; i2 < len2; i2 += 4) { + tmp = revLookup[b64.charCodeAt(i2)] << 18 | revLookup[b64.charCodeAt(i2 + 1)] << 12 | revLookup[b64.charCodeAt(i2 + 2)] << 6 | revLookup[b64.charCodeAt(i2 + 3)]; + arr[curByte++] = tmp >> 16 & 255; + arr[curByte++] = tmp >> 8 & 255; + arr[curByte++] = tmp & 255; + } + if (placeHoldersLen === 2) { + tmp = revLookup[b64.charCodeAt(i2)] << 2 | revLookup[b64.charCodeAt(i2 + 1)] >> 4; + arr[curByte++] = tmp & 255; + } + if (placeHoldersLen === 1) { + tmp = revLookup[b64.charCodeAt(i2)] << 10 | revLookup[b64.charCodeAt(i2 + 1)] << 4 | revLookup[b64.charCodeAt(i2 + 2)] >> 2; + arr[curByte++] = tmp >> 8 & 255; + arr[curByte++] = tmp & 255; + } + return arr; + } + function tripletToBase64(num) { + return lookup[num >> 18 & 63] + lookup[num >> 12 & 63] + lookup[num >> 6 & 63] + lookup[num & 63]; + } + function encodeChunk(uint8, start, end) { + var tmp; + var output = []; + for (var i2 = start; i2 < end; i2 += 3) { + tmp = (uint8[i2] << 16 & 16711680) + (uint8[i2 + 1] << 8 & 65280) + (uint8[i2 + 2] & 255); + output.push(tripletToBase64(tmp)); + } + return output.join(""); + } + function fromByteArray2(uint8) { + var tmp; + var len2 = uint8.length; + var extraBytes = len2 % 3; + var parts = []; + var maxChunkLength = 16383; + for (var i2 = 0, len22 = len2 - extraBytes; i2 < len22; i2 += maxChunkLength) parts.push(encodeChunk(uint8, i2, i2 + maxChunkLength > len22 ? len22 : i2 + maxChunkLength)); + if (extraBytes === 1) { + tmp = uint8[len2 - 1]; + parts.push(lookup[tmp >> 2] + lookup[tmp << 4 & 63] + "=="); + } else if (extraBytes === 2) { + tmp = (uint8[len2 - 2] << 8) + uint8[len2 - 1]; + parts.push(lookup[tmp >> 10] + lookup[tmp >> 4 & 63] + lookup[tmp << 2 & 63] + "="); + } + return parts.join(""); + } +} }); +var require_codes = __commonJS({ "../../node_modules/.pnpm/statuses@2.0.2/node_modules/statuses/codes.json"(exports, module) { + module.exports = { + "100": "Continue", + "101": "Switching Protocols", + "102": "Processing", + "103": "Early Hints", + "200": "OK", + "201": "Created", + "202": "Accepted", + "203": "Non-Authoritative Information", + "204": "No Content", + "205": "Reset Content", + "206": "Partial Content", + "207": "Multi-Status", + "208": "Already Reported", + "226": "IM Used", + "300": "Multiple Choices", + "301": "Moved Permanently", + "302": "Found", + "303": "See Other", + "304": "Not Modified", + "305": "Use Proxy", + "307": "Temporary Redirect", + "308": "Permanent Redirect", + "400": "Bad Request", + "401": "Unauthorized", + "402": "Payment Required", + "403": "Forbidden", + "404": "Not Found", + "405": "Method Not Allowed", + "406": "Not Acceptable", + "407": "Proxy Authentication Required", + "408": "Request Timeout", + "409": "Conflict", + "410": "Gone", + "411": "Length Required", + "412": "Precondition Failed", + "413": "Payload Too Large", + "414": "URI Too Long", + "415": "Unsupported Media Type", + "416": "Range Not Satisfiable", + "417": "Expectation Failed", + "418": "I'm a Teapot", + "421": "Misdirected Request", + "422": "Unprocessable Entity", + "423": "Locked", + "424": "Failed Dependency", + "425": "Too Early", + "426": "Upgrade Required", + "428": "Precondition Required", + "429": "Too Many Requests", + "431": "Request Header Fields Too Large", + "451": "Unavailable For Legal Reasons", + "500": "Internal Server Error", + "501": "Not Implemented", + "502": "Bad Gateway", + "503": "Service Unavailable", + "504": "Gateway Timeout", + "505": "HTTP Version Not Supported", + "506": "Variant Also Negotiates", + "507": "Insufficient Storage", + "508": "Loop Detected", + "509": "Bandwidth Limit Exceeded", + "510": "Not Extended", + "511": "Network Authentication Required" + }; +} }); +var require_statuses = __commonJS({ "../../node_modules/.pnpm/statuses@2.0.2/node_modules/statuses/index.js"(exports, module) { + var codes = require_codes(); + module.exports = status2; + status2.message = codes; + status2.code = createMessageToStatusCodeMap(codes); + status2.codes = createStatusCodeList(codes); + status2.redirect = { + 300: true, + 301: true, + 302: true, + 303: true, + 305: true, + 307: true, + 308: true + }; + status2.empty = { + 204: true, + 205: true, + 304: true + }; + status2.retry = { + 502: true, + 503: true, + 504: true + }; + function createMessageToStatusCodeMap(codes2) { + var map = {}; + Object.keys(codes2).forEach(function forEachCode(code) { + var message = codes2[code]; + var status3 = Number(code); + map[message.toLowerCase()] = status3; + }); + return map; + } + function createStatusCodeList(codes2) { + return Object.keys(codes2).map(function mapCode(code) { + return Number(code); + }); + } + function getStatusCode(message) { + var msg = message.toLowerCase(); + if (!Object.prototype.hasOwnProperty.call(status2.code, msg)) throw new Error("invalid status message: \"" + message + "\""); + return status2.code[msg]; + } + function getStatusMessage(code) { + if (!Object.prototype.hasOwnProperty.call(status2.message, code)) throw new Error("invalid status code: " + code); + return status2.message[code]; + } + function status2(code) { + if (typeof code === "number") return getStatusMessage(code); + if (typeof code !== "string") throw new TypeError("code must be a number or string"); + var n = parseInt(code, 10); + if (!isNaN(n)) return getStatusMessage(n); + return getStatusCode(code); + } +} }); +var util_stub_exports = {}; +__export(util_stub_exports, { inspect: () => inspect }); +var inspect; +var init_util_stub = __esm({ "src/util-stub.ts"() { + inspect = {}; +} }); +var require_util_inspect = __commonJS({ "../../node_modules/.pnpm/object-inspect@1.13.4/node_modules/object-inspect/util.inspect.js"(exports, module) { + module.exports = (init_util_stub(), __toCommonJS(util_stub_exports)).inspect; +} }); +var require_object_inspect = __commonJS({ "../../node_modules/.pnpm/object-inspect@1.13.4/node_modules/object-inspect/index.js"(exports, module) { + var hasMap = typeof Map === "function" && Map.prototype; + var mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, "size") : null; + var mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === "function" ? mapSizeDescriptor.get : null; + var mapForEach = hasMap && Map.prototype.forEach; + var hasSet = typeof Set === "function" && Set.prototype; + var setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, "size") : null; + var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === "function" ? setSizeDescriptor.get : null; + var setForEach = hasSet && Set.prototype.forEach; + var weakMapHas = typeof WeakMap === "function" && WeakMap.prototype ? WeakMap.prototype.has : null; + var weakSetHas = typeof WeakSet === "function" && WeakSet.prototype ? WeakSet.prototype.has : null; + var weakRefDeref = typeof WeakRef === "function" && WeakRef.prototype ? WeakRef.prototype.deref : null; + var booleanValueOf = Boolean.prototype.valueOf; + var objectToString = Object.prototype.toString; + var functionToString = Function.prototype.toString; + var $match = String.prototype.match; + var $slice = String.prototype.slice; + var $replace = String.prototype.replace; + var $toUpperCase = String.prototype.toUpperCase; + var $toLowerCase = String.prototype.toLowerCase; + var $test = RegExp.prototype.test; + var $concat = Array.prototype.concat; + var $join = Array.prototype.join; + var $arrSlice = Array.prototype.slice; + var $floor = Math.floor; + var bigIntValueOf = typeof BigInt === "function" ? BigInt.prototype.valueOf : null; + var gOPS = Object.getOwnPropertySymbols; + var symToString = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? Symbol.prototype.toString : null; + var hasShammedSymbols = typeof Symbol === "function" && typeof Symbol.iterator === "object"; + var toStringTag = typeof Symbol === "function" && Symbol.toStringTag && (typeof Symbol.toStringTag === hasShammedSymbols ? "object" : "symbol") ? Symbol.toStringTag : null; + var isEnumerable = Object.prototype.propertyIsEnumerable; + var gPO = (typeof Reflect === "function" ? Reflect.getPrototypeOf : Object.getPrototypeOf) || ([].__proto__ === Array.prototype ? function(O) { + return O.__proto__; + } : null); + function addNumericSeparator(num, str) { + if (num === Infinity || num === -Infinity || num !== num || num && num > -1e3 && num < 1e3 || $test.call(/e/, str)) return str; + var sepRegex = /[0-9](?=(?:[0-9]{3})+(?![0-9]))/g; + if (typeof num === "number") { + var int = num < 0 ? -$floor(-num) : $floor(num); + if (int !== num) { + var intStr = String(int); + var dec = $slice.call(str, intStr.length + 1); + return $replace.call(intStr, sepRegex, "$&_") + "." + $replace.call($replace.call(dec, /([0-9]{3})/g, "$&_"), /_$/, ""); + } + } + return $replace.call(str, sepRegex, "$&_"); + } + var utilInspect = require_util_inspect(); + var inspectCustom = utilInspect.custom; + var inspectSymbol = isSymbol(inspectCustom) ? inspectCustom : null; + var quotes = { + __proto__: null, + "double": "\"", + single: "'" + }; + var quoteREs = { + __proto__: null, + "double": /(["\\])/g, + single: /(['\\])/g + }; + module.exports = function inspect_(obj, options, depth, seen) { + var opts = options || {}; + if (has(opts, "quoteStyle") && !has(quotes, opts.quoteStyle)) throw new TypeError("option \"quoteStyle\" must be \"single\" or \"double\""); + if (has(opts, "maxStringLength") && (typeof opts.maxStringLength === "number" ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity : opts.maxStringLength !== null)) throw new TypeError("option \"maxStringLength\", if provided, must be a positive integer, Infinity, or `null`"); + var customInspect = has(opts, "customInspect") ? opts.customInspect : true; + if (typeof customInspect !== "boolean" && customInspect !== "symbol") throw new TypeError("option \"customInspect\", if provided, must be `true`, `false`, or `'symbol'`"); + if (has(opts, "indent") && opts.indent !== null && opts.indent !== " " && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)) throw new TypeError("option \"indent\" must be \"\\t\", an integer > 0, or `null`"); + if (has(opts, "numericSeparator") && typeof opts.numericSeparator !== "boolean") throw new TypeError("option \"numericSeparator\", if provided, must be `true` or `false`"); + var numericSeparator = opts.numericSeparator; + if (typeof obj === "undefined") return "undefined"; + if (obj === null) return "null"; + if (typeof obj === "boolean") return obj ? "true" : "false"; + if (typeof obj === "string") return inspectString(obj, opts); + if (typeof obj === "number") { + if (obj === 0) return Infinity / obj > 0 ? "0" : "-0"; + var str = String(obj); + return numericSeparator ? addNumericSeparator(obj, str) : str; + } + if (typeof obj === "bigint") { + var bigIntStr = String(obj) + "n"; + return numericSeparator ? addNumericSeparator(obj, bigIntStr) : bigIntStr; + } + var maxDepth = typeof opts.depth === "undefined" ? 5 : opts.depth; + if (typeof depth === "undefined") depth = 0; + if (depth >= maxDepth && maxDepth > 0 && typeof obj === "object") return isArray(obj) ? "[Array]" : "[Object]"; + var indent = getIndent(opts, depth); + if (typeof seen === "undefined") seen = []; + else if (indexOf(seen, obj) >= 0) return "[Circular]"; + function inspect3(value, from, noIndent) { + if (from) { + seen = $arrSlice.call(seen); + seen.push(from); + } + if (noIndent) { + var newOpts = { depth: opts.depth }; + if (has(opts, "quoteStyle")) newOpts.quoteStyle = opts.quoteStyle; + return inspect_(value, newOpts, depth + 1, seen); + } + return inspect_(value, opts, depth + 1, seen); + } + if (typeof obj === "function" && !isRegExp(obj)) { + var name = nameOf(obj); + var keys = arrObjKeys(obj, inspect3); + return "[Function" + (name ? ": " + name : " (anonymous)") + "]" + (keys.length > 0 ? " { " + $join.call(keys, ", ") + " }" : ""); + } + if (isSymbol(obj)) { + var symString = hasShammedSymbols ? $replace.call(String(obj), /^(Symbol\(.*\))_[^)]*$/, "$1") : symToString.call(obj); + return typeof obj === "object" && !hasShammedSymbols ? markBoxed(symString) : symString; + } + if (isElement(obj)) { + var s = "<" + $toLowerCase.call(String(obj.nodeName)); + var attrs = obj.attributes || []; + for (var i = 0; i < attrs.length; i++) s += " " + attrs[i].name + "=" + wrapQuotes(quote(attrs[i].value), "double", opts); + s += ">"; + if (obj.childNodes && obj.childNodes.length) s += "..."; + s += ""; + return s; + } + if (isArray(obj)) { + if (obj.length === 0) return "[]"; + var xs = arrObjKeys(obj, inspect3); + if (indent && !singleLineValues(xs)) return "[" + indentedJoin(xs, indent) + "]"; + return "[ " + $join.call(xs, ", ") + " ]"; + } + if (isError(obj)) { + var parts = arrObjKeys(obj, inspect3); + if (!("cause" in Error.prototype) && "cause" in obj && !isEnumerable.call(obj, "cause")) return "{ [" + String(obj) + "] " + $join.call($concat.call("[cause]: " + inspect3(obj.cause), parts), ", ") + " }"; + if (parts.length === 0) return "[" + String(obj) + "]"; + return "{ [" + String(obj) + "] " + $join.call(parts, ", ") + " }"; + } + if (typeof obj === "object" && customInspect) { + if (inspectSymbol && typeof obj[inspectSymbol] === "function" && utilInspect) return utilInspect(obj, { depth: maxDepth - depth }); + else if (customInspect !== "symbol" && typeof obj.inspect === "function") return obj.inspect(); + } + if (isMap(obj)) { + var mapParts = []; + if (mapForEach) mapForEach.call(obj, function(value, key) { + mapParts.push(inspect3(key, obj, true) + " => " + inspect3(value, obj)); + }); + return collectionOf("Map", mapSize.call(obj), mapParts, indent); + } + if (isSet(obj)) { + var setParts = []; + if (setForEach) setForEach.call(obj, function(value) { + setParts.push(inspect3(value, obj)); + }); + return collectionOf("Set", setSize.call(obj), setParts, indent); + } + if (isWeakMap(obj)) return weakCollectionOf("WeakMap"); + if (isWeakSet(obj)) return weakCollectionOf("WeakSet"); + if (isWeakRef(obj)) return weakCollectionOf("WeakRef"); + if (isNumber(obj)) return markBoxed(inspect3(Number(obj))); + if (isBigInt(obj)) return markBoxed(inspect3(bigIntValueOf.call(obj))); + if (isBoolean(obj)) return markBoxed(booleanValueOf.call(obj)); + if (isString(obj)) return markBoxed(inspect3(String(obj))); + if (typeof window !== "undefined" && obj === window) return "{ [object Window] }"; + if (typeof globalThis !== "undefined" && obj === globalThis || typeof global !== "undefined" && obj === global) return "{ [object globalThis] }"; + if (!isDate(obj) && !isRegExp(obj)) { + var ys = arrObjKeys(obj, inspect3); + var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object; + var protoTag = obj instanceof Object ? "" : "null prototype"; + var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? $slice.call(toStr(obj), 8, -1) : protoTag ? "Object" : ""; + var tag = (isPlainObject || typeof obj.constructor !== "function" ? "" : obj.constructor.name ? obj.constructor.name + " " : "") + (stringTag || protoTag ? "[" + $join.call($concat.call([], stringTag || [], protoTag || []), ": ") + "] " : ""); + if (ys.length === 0) return tag + "{}"; + if (indent) return tag + "{" + indentedJoin(ys, indent) + "}"; + return tag + "{ " + $join.call(ys, ", ") + " }"; + } + return String(obj); + }; + function wrapQuotes(s, defaultStyle, opts) { + var quoteChar = quotes[opts.quoteStyle || defaultStyle]; + return quoteChar + s + quoteChar; + } + function quote(s) { + return $replace.call(String(s), /"/g, """); + } + function canTrustToString(obj) { + return !toStringTag || !(typeof obj === "object" && (toStringTag in obj || typeof obj[toStringTag] !== "undefined")); + } + function isArray(obj) { + return toStr(obj) === "[object Array]" && canTrustToString(obj); + } + function isDate(obj) { + return toStr(obj) === "[object Date]" && canTrustToString(obj); + } + function isRegExp(obj) { + return toStr(obj) === "[object RegExp]" && canTrustToString(obj); + } + function isError(obj) { + return toStr(obj) === "[object Error]" && canTrustToString(obj); + } + function isString(obj) { + return toStr(obj) === "[object String]" && canTrustToString(obj); + } + function isNumber(obj) { + return toStr(obj) === "[object Number]" && canTrustToString(obj); + } + function isBoolean(obj) { + return toStr(obj) === "[object Boolean]" && canTrustToString(obj); + } + function isSymbol(obj) { + if (hasShammedSymbols) return obj && typeof obj === "object" && obj instanceof Symbol; + if (typeof obj === "symbol") return true; + if (!obj || typeof obj !== "object" || !symToString) return false; + try { + symToString.call(obj); + return true; + } catch (e) {} + return false; + } + function isBigInt(obj) { + if (!obj || typeof obj !== "object" || !bigIntValueOf) return false; + try { + bigIntValueOf.call(obj); + return true; + } catch (e) {} + return false; + } + var hasOwn2 = Object.prototype.hasOwnProperty || function(key) { + return key in this; + }; + function has(obj, key) { + return hasOwn2.call(obj, key); + } + function toStr(obj) { + return objectToString.call(obj); + } + function nameOf(f) { + if (f.name) return f.name; + var m = $match.call(functionToString.call(f), /^function\s*([\w$]+)/); + if (m) return m[1]; + return null; + } + function indexOf(xs, x) { + if (xs.indexOf) return xs.indexOf(x); + for (var i = 0, l = xs.length; i < l; i++) if (xs[i] === x) return i; + return -1; + } + function isMap(x) { + if (!mapSize || !x || typeof x !== "object") return false; + try { + mapSize.call(x); + try { + setSize.call(x); + } catch (s) { + return true; + } + return x instanceof Map; + } catch (e) {} + return false; + } + function isWeakMap(x) { + if (!weakMapHas || !x || typeof x !== "object") return false; + try { + weakMapHas.call(x, weakMapHas); + try { + weakSetHas.call(x, weakSetHas); + } catch (s) { + return true; + } + return x instanceof WeakMap; + } catch (e) {} + return false; + } + function isWeakRef(x) { + if (!weakRefDeref || !x || typeof x !== "object") return false; + try { + weakRefDeref.call(x); + return true; + } catch (e) {} + return false; + } + function isSet(x) { + if (!setSize || !x || typeof x !== "object") return false; + try { + setSize.call(x); + try { + mapSize.call(x); + } catch (m) { + return true; + } + return x instanceof Set; + } catch (e) {} + return false; + } + function isWeakSet(x) { + if (!weakSetHas || !x || typeof x !== "object") return false; + try { + weakSetHas.call(x, weakSetHas); + try { + weakMapHas.call(x, weakMapHas); + } catch (s) { + return true; + } + return x instanceof WeakSet; + } catch (e) {} + return false; + } + function isElement(x) { + if (!x || typeof x !== "object") return false; + if (typeof HTMLElement !== "undefined" && x instanceof HTMLElement) return true; + return typeof x.nodeName === "string" && typeof x.getAttribute === "function"; + } + function inspectString(str, opts) { + if (str.length > opts.maxStringLength) { + var remaining = str.length - opts.maxStringLength; + var trailer = "... " + remaining + " more character" + (remaining > 1 ? "s" : ""); + return inspectString($slice.call(str, 0, opts.maxStringLength), opts) + trailer; + } + var quoteRE = quoteREs[opts.quoteStyle || "single"]; + quoteRE.lastIndex = 0; + return wrapQuotes($replace.call($replace.call(str, quoteRE, "\\$1"), /[\x00-\x1f]/g, lowbyte), "single", opts); + } + function lowbyte(c) { + var n = c.charCodeAt(0); + var x = { + 8: "b", + 9: "t", + 10: "n", + 12: "f", + 13: "r" + }[n]; + if (x) return "\\" + x; + return "\\x" + (n < 16 ? "0" : "") + $toUpperCase.call(n.toString(16)); + } + function markBoxed(str) { + return "Object(" + str + ")"; + } + function weakCollectionOf(type) { + return type + " { ? }"; + } + function collectionOf(type, size, entries, indent) { + var joinedEntries = indent ? indentedJoin(entries, indent) : $join.call(entries, ", "); + return type + " (" + size + ") {" + joinedEntries + "}"; + } + function singleLineValues(xs) { + for (var i = 0; i < xs.length; i++) if (indexOf(xs[i], "\n") >= 0) return false; + return true; + } + function getIndent(opts, depth) { + var baseIndent; + if (opts.indent === " ") baseIndent = " "; + else if (typeof opts.indent === "number" && opts.indent > 0) baseIndent = $join.call(Array(opts.indent + 1), " "); + else return null; + return { + base: baseIndent, + prev: $join.call(Array(depth + 1), baseIndent) + }; + } + function indentedJoin(xs, indent) { + if (xs.length === 0) return ""; + var lineJoiner = "\n" + indent.prev + indent.base; + return lineJoiner + $join.call(xs, "," + lineJoiner) + "\n" + indent.prev; + } + function arrObjKeys(obj, inspect3) { + var isArr = isArray(obj); + var xs = []; + if (isArr) { + xs.length = obj.length; + for (var i = 0; i < obj.length; i++) xs[i] = has(obj, i) ? inspect3(obj[i], obj) : ""; + } + var syms = typeof gOPS === "function" ? gOPS(obj) : []; + var symMap; + if (hasShammedSymbols) { + symMap = {}; + for (var k = 0; k < syms.length; k++) symMap["$" + syms[k]] = syms[k]; + } + for (var key in obj) { + if (!has(obj, key)) continue; + if (isArr && String(Number(key)) === key && key < obj.length) continue; + if (hasShammedSymbols && symMap["$" + key] instanceof Symbol) continue; + else if ($test.call(/[^\w$]/, key)) xs.push(inspect3(key, obj) + ": " + inspect3(obj[key], obj)); + else xs.push(key + ": " + inspect3(obj[key], obj)); + } + if (typeof gOPS === "function") { + for (var j = 0; j < syms.length; j++) if (isEnumerable.call(obj, syms[j])) xs.push("[" + inspect3(syms[j]) + "]: " + inspect3(obj[syms[j]], obj)); + } + return xs; + } +} }); +var TimeDuration = class _TimeDuration { + __time_duration_micros__; + static MICROS_PER_MILLIS = 1000n; + /** + * Get the algebraic type representation of the {@link TimeDuration} type. + * @returns The algebraic type representation of the type. + */ + static getAlgebraicType() { + return AlgebraicType.Product({ elements: [{ + name: "__time_duration_micros__", + algebraicType: AlgebraicType.I64 + }] }); + } + static isTimeDuration(algebraicType) { + if (algebraicType.tag !== "Product") return false; + const elements = algebraicType.value.elements; + if (elements.length !== 1) return false; + const microsElement = elements[0]; + return microsElement.name === "__time_duration_micros__" && microsElement.algebraicType.tag === "I64"; + } + get micros() { + return this.__time_duration_micros__; + } + get millis() { + return Number(this.micros / _TimeDuration.MICROS_PER_MILLIS); + } + constructor(micros) { + this.__time_duration_micros__ = micros; + } + static fromMillis(millis) { + return new _TimeDuration(BigInt(millis) * _TimeDuration.MICROS_PER_MILLIS); + } + /** This outputs the same string format that we use in the host and in Rust modules */ + toString() { + const micros = this.micros; + const sign = micros < 0 ? "-" : "+"; + const pos = micros < 0 ? -micros : micros; + const secs = pos / 1000000n; + const micros_remaining = pos % 1000000n; + return `${sign}${secs}.${String(micros_remaining).padStart(6, "0")}`; + } +}; +var Timestamp = class _Timestamp { + __timestamp_micros_since_unix_epoch__; + static MICROS_PER_MILLIS = 1000n; + get microsSinceUnixEpoch() { + return this.__timestamp_micros_since_unix_epoch__; + } + constructor(micros) { + this.__timestamp_micros_since_unix_epoch__ = micros; + } + /** + * Get the algebraic type representation of the {@link Timestamp} type. + * @returns The algebraic type representation of the type. + */ + static getAlgebraicType() { + return AlgebraicType.Product({ elements: [{ + name: "__timestamp_micros_since_unix_epoch__", + algebraicType: AlgebraicType.I64 + }] }); + } + static isTimestamp(algebraicType) { + if (algebraicType.tag !== "Product") return false; + const elements = algebraicType.value.elements; + if (elements.length !== 1) return false; + const microsElement = elements[0]; + return microsElement.name === "__timestamp_micros_since_unix_epoch__" && microsElement.algebraicType.tag === "I64"; + } + /** + * The Unix epoch, the midnight at the beginning of January 1, 1970, UTC. + */ + static UNIX_EPOCH = new _Timestamp(0n); + /** + * Get a `Timestamp` representing the execution environment's belief of the current moment in time. + */ + static now() { + return _Timestamp.fromDate(/* @__PURE__ */ new Date()); + } + /** Convert to milliseconds since Unix epoch. */ + toMillis() { + return this.microsSinceUnixEpoch / 1000n; + } + /** + * Get a `Timestamp` representing the same point in time as `date`. + */ + static fromDate(date) { + const millis = date.getTime(); + return new _Timestamp(BigInt(millis) * _Timestamp.MICROS_PER_MILLIS); + } + /** + * Get a `Date` representing approximately the same point in time as `this`. + * + * This method truncates to millisecond precision, + * and throws `RangeError` if the `Timestamp` is outside the range representable as a `Date`. + */ + toDate() { + const millis = this.__timestamp_micros_since_unix_epoch__ / _Timestamp.MICROS_PER_MILLIS; + if (millis > BigInt(Number.MAX_SAFE_INTEGER) || millis < BigInt(Number.MIN_SAFE_INTEGER)) throw new RangeError("Timestamp is outside of the representable range of JS's Date"); + return new Date(Number(millis)); + } + /** + * Get an ISO 8601 / RFC 3339 formatted string representation of this timestamp with microsecond precision. + * + * This method preserves the full microsecond precision of the timestamp, + * and throws `RangeError` if the `Timestamp` is outside the range representable in ISO format. + * + * @returns ISO 8601 formatted string with microsecond precision (e.g., '2025-02-17T10:30:45.123456Z') + */ + toISOString() { + const micros = this.__timestamp_micros_since_unix_epoch__; + const millis = micros / _Timestamp.MICROS_PER_MILLIS; + if (millis > BigInt(Number.MAX_SAFE_INTEGER) || millis < BigInt(Number.MIN_SAFE_INTEGER)) throw new RangeError("Timestamp is outside of the representable range for ISO string formatting"); + const isoBase = new Date(Number(millis)).toISOString(); + const microsRemainder = Math.abs(Number(micros % 1000000n)); + const fractionalPart = String(microsRemainder).padStart(6, "0"); + return isoBase.replace(/\.\d{3}Z$/, `.${fractionalPart}Z`); + } + since(other) { + return new TimeDuration(this.__timestamp_micros_since_unix_epoch__ - other.__timestamp_micros_since_unix_epoch__); + } +}; +var Uuid = class _Uuid { + __uuid__; + /** + * The nil UUID (all zeros). + * + * @example + * ```ts + * const uuid = Uuid.NIL; + * console.assert( + * uuid.toString() === "00000000-0000-0000-0000-000000000000" + * ); + * ``` + */ + static NIL = new _Uuid(0n); + static MAX_UUID_BIGINT = 340282366920938463463374607431768211455n; + /** + * The max UUID (all ones). + * + * @example + * ```ts + * const uuid = Uuid.MAX; + * console.assert( + * uuid.toString() === "ffffffff-ffff-ffff-ffff-ffffffffffff" + * ); + * ``` + */ + static MAX = new _Uuid(_Uuid.MAX_UUID_BIGINT); + /** + * Create a UUID from a raw 128-bit value. + * + * @param u - Unsigned 128-bit integer + * @throws {Error} If the value is outside the valid UUID range + */ + constructor(u) { + if (u < 0n || u > _Uuid.MAX_UUID_BIGINT) throw new Error("Invalid UUID: must be between 0 and `MAX_UUID_BIGINT`"); + this.__uuid__ = u; + } + /** + * Create a UUID `v4` from explicit random bytes. + * + * This method assumes the bytes are already sufficiently random. + * It only sets the appropriate bits for the UUID version and variant. + * + * @param bytes - Exactly 16 random bytes + * @returns A UUID `v4` + * @throws {Error} If `bytes.length !== 16` + * + * @example + * ```ts + * const randomBytes = new Uint8Array(16); + * const uuid = Uuid.fromRandomBytesV4(randomBytes); + * + * console.assert( + * uuid.toString() === "00000000-0000-4000-8000-000000000000" + * ); + * ``` + */ + static fromRandomBytesV4(bytes) { + if (bytes.length !== 16) throw new Error("UUID v4 requires 16 bytes"); + const arr = new Uint8Array(bytes); + arr[6] = arr[6] & 15 | 64; + arr[8] = arr[8] & 63 | 128; + return new _Uuid(_Uuid.bytesToBigInt(arr)); + } + /** + * Generate a UUID `v7` using a monotonic counter from `0` to `2^31 - 1`, + * a timestamp, and 4 random bytes. + * + * The counter wraps around on overflow. + * + * The UUID `v7` is structured as follows: + * + * ```ascii + * ┌───────────────────────────────────────────────┬───────────────────┐ + * | B0 | B1 | B2 | B3 | B4 | B5 | B6 | + * ├───────────────────────────────────────────────┼───────────────────┤ + * | unix_ts_ms | version 7 | + * └───────────────────────────────────────────────┴───────────────────┘ + * ┌──────────────┬─────────┬──────────────────┬───────────────────────┐ + * | B7 | B8 | B9 | B10 | B11 | B12 | B13 | B14 | B15 | + * ├──────────────┼─────────┼──────────────────┼───────────────────────┤ + * | counter_high | variant | counter_low | random | + * └──────────────┴─────────┴──────────────────┴───────────────────────┘ + * ``` + * + * @param counter - Mutable monotonic counter (31-bit) + * @param now - Timestamp since the Unix epoch + * @param randomBytes - Exactly 4 random bytes + * @returns A UUID `v7` + * + * @throws {Error} If the `counter` is negative + * @throws {Error} If the `timestamp` is before the Unix epoch + * @throws {Error} If `randomBytes.length !== 4` + * + * @example + * ```ts + * const now = Timestamp.fromMillis(1_686_000_000_000n); + * const counter = { value: 1 }; + * const randomBytes = new Uint8Array(4); + * + * const uuid = Uuid.fromCounterV7(counter, now, randomBytes); + * + * console.assert( + * uuid.toString() === "0000647e-5180-7000-8000-000200000000" + * ); + * ``` + */ + static fromCounterV7(counter, now, randomBytes) { + if (randomBytes.length !== 4) throw new Error("`fromCounterV7` requires `randomBytes.length == 4`"); + if (counter.value < 0) throw new Error("`fromCounterV7` uuid `counter` must be non-negative"); + if (now.__timestamp_micros_since_unix_epoch__ < 0) throw new Error("`fromCounterV7` `timestamp` before unix epoch"); + const counterVal = counter.value; + counter.value = counterVal + 1 & 2147483647; + const tsMs = now.toMillis() & 281474976710655n; + const bytes = new Uint8Array(16); + bytes[0] = Number(tsMs >> 40n & 255n); + bytes[1] = Number(tsMs >> 32n & 255n); + bytes[2] = Number(tsMs >> 24n & 255n); + bytes[3] = Number(tsMs >> 16n & 255n); + bytes[4] = Number(tsMs >> 8n & 255n); + bytes[5] = Number(tsMs & 255n); + bytes[7] = counterVal >>> 23 & 255; + bytes[9] = counterVal >>> 15 & 255; + bytes[10] = counterVal >>> 7 & 255; + bytes[11] = (counterVal & 127) << 1 & 255; + bytes[12] |= randomBytes[0] & 127; + bytes[13] = randomBytes[1]; + bytes[14] = randomBytes[2]; + bytes[15] = randomBytes[3]; + bytes[6] = bytes[6] & 15 | 112; + bytes[8] = bytes[8] & 63 | 128; + return new _Uuid(_Uuid.bytesToBigInt(bytes)); + } + /** + * Parse a UUID from a string representation. + * + * @param s - UUID string + * @returns Parsed UUID + * @throws {Error} If the string is not a valid UUID + * + * @example + * ```ts + * const s = "01888d6e-5c00-7000-8000-000000000000"; + * const uuid = Uuid.parse(s); + * + * console.assert(uuid.toString() === s); + * ``` + */ + static parse(s) { + const hex = s.replace(/-/g, ""); + if (hex.length !== 32) throw new Error("Invalid hex UUID"); + let v = 0n; + for (let i = 0; i < 32; i += 2) v = v << 8n | BigInt(parseInt(hex.slice(i, i + 2), 16)); + return new _Uuid(v); + } + /** Convert to string (hyphenated form). */ + toString() { + const hex = [..._Uuid.bigIntToBytes(this.__uuid__)].map((b) => b.toString(16).padStart(2, "0")).join(""); + return hex.slice(0, 8) + "-" + hex.slice(8, 12) + "-" + hex.slice(12, 16) + "-" + hex.slice(16, 20) + "-" + hex.slice(20); + } + /** Convert to bigint (u128). */ + asBigInt() { + return this.__uuid__; + } + /** Return a `Uint8Array` of 16 bytes. */ + toBytes() { + return _Uuid.bigIntToBytes(this.__uuid__); + } + static bytesToBigInt(bytes) { + let result = 0n; + for (const b of bytes) result = result << 8n | BigInt(b); + return result; + } + static bigIntToBytes(value) { + const bytes = new Uint8Array(16); + for (let i = 15; i >= 0; i--) { + bytes[i] = Number(value & 255n); + value >>= 8n; + } + return bytes; + } + /** + * Returns the version of this UUID. + * + * This represents the algorithm used to generate the value. + * + * @returns A `UuidVersion` + * @throws {Error} If the version field is not recognized + */ + getVersion() { + const version = this.toBytes()[6] >> 4 & 15; + switch (version) { + case 4: return "V4"; + case 7: return "V7"; + default: + if (this == _Uuid.NIL) return "Nil"; + if (this == _Uuid.MAX) return "Max"; + throw new Error(`Unsupported UUID version: ${version}`); + } + } + /** + * Extract the monotonic counter from a UUIDv7. + * + * Intended for testing and diagnostics. + * Behavior is undefined if called on a non-V7 UUID. + * + * @returns 31-bit counter value + */ + getCounter() { + const bytes = this.toBytes(); + const high = bytes[7]; + const mid1 = bytes[9]; + const mid2 = bytes[10]; + const low = bytes[11] >>> 1; + return high << 23 | mid1 << 15 | mid2 << 7 | low | 0; + } + compareTo(other) { + if (this.__uuid__ < other.__uuid__) return -1; + if (this.__uuid__ > other.__uuid__) return 1; + return 0; + } + static getAlgebraicType() { + return AlgebraicType.Product({ elements: [{ + name: "__uuid__", + algebraicType: AlgebraicType.U128 + }] }); + } +}; +var BinaryReader = class { + /** + * The DataView used to read values from the binary data. + * + * Note: The DataView's `byteOffset` is relative to the beginning of the + * underlying ArrayBuffer, not the start of the provided Uint8Array input. + * This `BinaryReader`'s `#offset` field is used to track the current read position + * relative to the start of the provided Uint8Array input. + */ + view; + /** + * Represents the offset (in bytes) relative to the start of the DataView + * and provided Uint8Array input. + * + * Note: This is *not* the absolute byte offset within the underlying ArrayBuffer. + */ + offset = 0; + constructor(input) { + this.view = input instanceof DataView ? input : new DataView(input.buffer, input.byteOffset, input.byteLength); + this.offset = 0; + } + reset(view) { + this.view = view; + this.offset = 0; + } + get remaining() { + return this.view.byteLength - this.offset; + } + /** Ensure we have at least `n` bytes left to read */ + #ensure(n) { + if (this.offset + n > this.view.byteLength) throw new RangeError(`Tried to read ${n} byte(s) at relative offset ${this.offset}, but only ${this.remaining} byte(s) remain`); + } + readUInt8Array() { + const length = this.readU32(); + this.#ensure(length); + return this.readBytes(length); + } + readBool() { + const value = this.view.getUint8(this.offset); + this.offset += 1; + return value !== 0; + } + readByte() { + const value = this.view.getUint8(this.offset); + this.offset += 1; + return value; + } + readBytes(length) { + const array = new Uint8Array(this.view.buffer, this.view.byteOffset + this.offset, length); + this.offset += length; + return array; + } + readI8() { + const value = this.view.getInt8(this.offset); + this.offset += 1; + return value; + } + readU8() { + return this.readByte(); + } + readI16() { + const value = this.view.getInt16(this.offset, true); + this.offset += 2; + return value; + } + readU16() { + const value = this.view.getUint16(this.offset, true); + this.offset += 2; + return value; + } + readI32() { + const value = this.view.getInt32(this.offset, true); + this.offset += 4; + return value; + } + readU32() { + const value = this.view.getUint32(this.offset, true); + this.offset += 4; + return value; + } + readI64() { + const value = this.view.getBigInt64(this.offset, true); + this.offset += 8; + return value; + } + readU64() { + const value = this.view.getBigUint64(this.offset, true); + this.offset += 8; + return value; + } + readU128() { + const lowerPart = this.view.getBigUint64(this.offset, true); + const upperPart = this.view.getBigUint64(this.offset + 8, true); + this.offset += 16; + return (upperPart << BigInt(64)) + lowerPart; + } + readI128() { + const lowerPart = this.view.getBigUint64(this.offset, true); + const upperPart = this.view.getBigInt64(this.offset + 8, true); + this.offset += 16; + return (upperPart << BigInt(64)) + lowerPart; + } + readU256() { + const p0 = this.view.getBigUint64(this.offset, true); + const p1 = this.view.getBigUint64(this.offset + 8, true); + const p2 = this.view.getBigUint64(this.offset + 16, true); + const p3 = this.view.getBigUint64(this.offset + 24, true); + this.offset += 32; + return (p3 << BigInt(192)) + (p2 << BigInt(128)) + (p1 << BigInt(64)) + p0; + } + readI256() { + const p0 = this.view.getBigUint64(this.offset, true); + const p1 = this.view.getBigUint64(this.offset + 8, true); + const p2 = this.view.getBigUint64(this.offset + 16, true); + const p3 = this.view.getBigInt64(this.offset + 24, true); + this.offset += 32; + return (p3 << BigInt(192)) + (p2 << BigInt(128)) + (p1 << BigInt(64)) + p0; + } + readF32() { + const value = this.view.getFloat32(this.offset, true); + this.offset += 4; + return value; + } + readF64() { + const value = this.view.getFloat64(this.offset, true); + this.offset += 8; + return value; + } + readString() { + const uint8Array = this.readUInt8Array(); + return new TextDecoder("utf-8").decode(uint8Array); + } +}; +var import_base64_js = __toESM(require_base64_js()); +var ArrayBufferPrototypeTransfer = ArrayBuffer.prototype.transfer ?? function(newByteLength) { + if (newByteLength === void 0) return this.slice(); + else if (newByteLength <= this.byteLength) return this.slice(0, newByteLength); + else { + const copy = new Uint8Array(newByteLength); + copy.set(new Uint8Array(this)); + return copy.buffer; + } +}; +var ResizableBuffer = class { + buffer; + view; + constructor(init) { + this.buffer = typeof init === "number" ? new ArrayBuffer(init) : init; + this.view = new DataView(this.buffer); + } + get capacity() { + return this.buffer.byteLength; + } + grow(newSize) { + if (newSize <= this.buffer.byteLength) return; + this.buffer = ArrayBufferPrototypeTransfer.call(this.buffer, newSize); + this.view = new DataView(this.buffer); + } +}; +var BinaryWriter = class { + buffer; + offset = 0; + constructor(init) { + this.buffer = typeof init === "number" ? new ResizableBuffer(init) : init; + } + clear() { + this.offset = 0; + } + reset(buffer) { + this.buffer = buffer; + this.offset = 0; + } + expandBuffer(additionalCapacity) { + const minCapacity = this.offset + additionalCapacity + 1; + if (minCapacity <= this.buffer.capacity) return; + let newCapacity = this.buffer.capacity * 2; + if (newCapacity < minCapacity) newCapacity = minCapacity; + this.buffer.grow(newCapacity); + } + toBase64() { + return (0, import_base64_js.fromByteArray)(this.getBuffer()); + } + getBuffer() { + return new Uint8Array(this.buffer.buffer, 0, this.offset); + } + get view() { + return this.buffer.view; + } + writeUInt8Array(value) { + const length = value.length; + this.expandBuffer(4 + length); + this.writeU32(length); + new Uint8Array(this.buffer.buffer, this.offset).set(value); + this.offset += length; + } + writeBool(value) { + this.expandBuffer(1); + this.view.setUint8(this.offset, value ? 1 : 0); + this.offset += 1; + } + writeByte(value) { + this.expandBuffer(1); + this.view.setUint8(this.offset, value); + this.offset += 1; + } + writeI8(value) { + this.expandBuffer(1); + this.view.setInt8(this.offset, value); + this.offset += 1; + } + writeU8(value) { + this.expandBuffer(1); + this.view.setUint8(this.offset, value); + this.offset += 1; + } + writeI16(value) { + this.expandBuffer(2); + this.view.setInt16(this.offset, value, true); + this.offset += 2; + } + writeU16(value) { + this.expandBuffer(2); + this.view.setUint16(this.offset, value, true); + this.offset += 2; + } + writeI32(value) { + this.expandBuffer(4); + this.view.setInt32(this.offset, value, true); + this.offset += 4; + } + writeU32(value) { + this.expandBuffer(4); + this.view.setUint32(this.offset, value, true); + this.offset += 4; + } + writeI64(value) { + this.expandBuffer(8); + this.view.setBigInt64(this.offset, value, true); + this.offset += 8; + } + writeU64(value) { + this.expandBuffer(8); + this.view.setBigUint64(this.offset, value, true); + this.offset += 8; + } + writeU128(value) { + this.expandBuffer(16); + const lowerPart = value & BigInt("0xFFFFFFFFFFFFFFFF"); + const upperPart = value >> BigInt(64); + this.view.setBigUint64(this.offset, lowerPart, true); + this.view.setBigUint64(this.offset + 8, upperPart, true); + this.offset += 16; + } + writeI128(value) { + this.expandBuffer(16); + const lowerPart = value & BigInt("0xFFFFFFFFFFFFFFFF"); + const upperPart = value >> BigInt(64); + this.view.setBigInt64(this.offset, lowerPart, true); + this.view.setBigInt64(this.offset + 8, upperPart, true); + this.offset += 16; + } + writeU256(value) { + this.expandBuffer(32); + const low_64_mask = BigInt("0xFFFFFFFFFFFFFFFF"); + const p0 = value & low_64_mask; + const p1 = value >> BigInt(64) & low_64_mask; + const p2 = value >> BigInt(128) & low_64_mask; + const p3 = value >> BigInt(192); + this.view.setBigUint64(this.offset + 0, p0, true); + this.view.setBigUint64(this.offset + 8, p1, true); + this.view.setBigUint64(this.offset + 16, p2, true); + this.view.setBigUint64(this.offset + 24, p3, true); + this.offset += 32; + } + writeI256(value) { + this.expandBuffer(32); + const low_64_mask = BigInt("0xFFFFFFFFFFFFFFFF"); + const p0 = value & low_64_mask; + const p1 = value >> BigInt(64) & low_64_mask; + const p2 = value >> BigInt(128) & low_64_mask; + const p3 = value >> BigInt(192); + this.view.setBigUint64(this.offset + 0, p0, true); + this.view.setBigUint64(this.offset + 8, p1, true); + this.view.setBigUint64(this.offset + 16, p2, true); + this.view.setBigInt64(this.offset + 24, p3, true); + this.offset += 32; + } + writeF32(value) { + this.expandBuffer(4); + this.view.setFloat32(this.offset, value, true); + this.offset += 4; + } + writeF64(value) { + this.expandBuffer(8); + this.view.setFloat64(this.offset, value, true); + this.offset += 8; + } + writeString(value) { + const encodedString = new TextEncoder().encode(value); + this.writeUInt8Array(encodedString); + } +}; +function uint8ArrayToHexString(array) { + return Array.prototype.map.call(array.reverse(), (x) => ("00" + x.toString(16)).slice(-2)).join(""); +} +function uint8ArrayToU128(array) { + if (array.length != 16) throw new Error(`Uint8Array is not 16 bytes long: ${array}`); + return new BinaryReader(array).readU128(); +} +function uint8ArrayToU256(array) { + if (array.length != 32) throw new Error(`Uint8Array is not 32 bytes long: [${array}]`); + return new BinaryReader(array).readU256(); +} +function hexStringToUint8Array(str) { + if (str.startsWith("0x")) str = str.slice(2); + const matches = str.match(/.{1,2}/g) || []; + return Uint8Array.from(matches.map((byte) => parseInt(byte, 16))).reverse(); +} +function hexStringToU128(str) { + return uint8ArrayToU128(hexStringToUint8Array(str)); +} +function hexStringToU256(str) { + return uint8ArrayToU256(hexStringToUint8Array(str)); +} +function u128ToUint8Array(data) { + const writer = new BinaryWriter(16); + writer.writeU128(data); + return writer.getBuffer(); +} +function u128ToHexString(data) { + return uint8ArrayToHexString(u128ToUint8Array(data)); +} +function u256ToUint8Array(data) { + const writer = new BinaryWriter(32); + writer.writeU256(data); + return writer.getBuffer(); +} +function u256ToHexString(data) { + return uint8ArrayToHexString(u256ToUint8Array(data)); +} +function toPascalCase(s) { + const str = toCamelCase(s); + return str.charAt(0).toUpperCase() + str.slice(1); +} +function toCamelCase(s) { + const str = s.replace(/[-_]+/g, "_").replace(/_([a-zA-Z0-9])/g, (_, c) => c.toUpperCase()); + return str.charAt(0).toLowerCase() + str.slice(1); +} +function bsatnBaseSize(typespace, ty) { + const assumedArrayLength = 4; + while (ty.tag === "Ref") ty = typespace.types[ty.value]; + if (ty.tag === "Product") { + let sum = 0; + for (const { algebraicType: elem } of ty.value.elements) sum += bsatnBaseSize(typespace, elem); + return sum; + } else if (ty.tag === "Sum") { + let min = Infinity; + for (const { algebraicType: vari } of ty.value.variants) { + const vSize = bsatnBaseSize(typespace, vari); + if (vSize < min) min = vSize; + } + if (min === Infinity) min = 0; + return 4 + min; + } else if (ty.tag == "Array") return 4 + assumedArrayLength * bsatnBaseSize(typespace, ty.value); + return { + String: 4 + assumedArrayLength, + Sum: 1, + Bool: 1, + I8: 1, + U8: 1, + I16: 2, + U16: 2, + I32: 4, + U32: 4, + F32: 4, + I64: 8, + U64: 8, + F64: 8, + I128: 16, + U128: 16, + I256: 32, + U256: 32 + }[ty.tag]; +} +var hasOwn = Object.hasOwn; +var ConnectionId = class _ConnectionId { + __connection_id__; + /** + * Creates a new `ConnectionId`. + */ + constructor(data) { + this.__connection_id__ = data; + } + /** + * Get the algebraic type representation of the {@link ConnectionId} type. + * @returns The algebraic type representation of the type. + */ + static getAlgebraicType() { + return AlgebraicType.Product({ elements: [{ + name: "__connection_id__", + algebraicType: AlgebraicType.U128 + }] }); + } + isZero() { + return this.__connection_id__ === BigInt(0); + } + static nullIfZero(addr) { + if (addr.isZero()) return null; + else return addr; + } + static random() { + function randomU8() { + return Math.floor(Math.random() * 255); + } + let result = BigInt(0); + for (let i = 0; i < 16; i++) result = result << BigInt(8) | BigInt(randomU8()); + return new _ConnectionId(result); + } + /** + * Compare two connection IDs for equality. + */ + isEqual(other) { + return this.__connection_id__ == other.__connection_id__; + } + /** + * Check if two connection IDs are equal. + */ + equals(other) { + return this.isEqual(other); + } + /** + * Print the connection ID as a hexadecimal string. + */ + toHexString() { + return u128ToHexString(this.__connection_id__); + } + /** + * Convert the connection ID to a Uint8Array. + */ + toUint8Array() { + return u128ToUint8Array(this.__connection_id__); + } + /** + * Parse a connection ID from a hexadecimal string. + */ + static fromString(str) { + return new _ConnectionId(hexStringToU128(str)); + } + static fromStringOrNull(str) { + const addr = _ConnectionId.fromString(str); + if (addr.isZero()) return null; + else return addr; + } +}; +var Identity = class _Identity { + __identity__; + /** + * Creates a new `Identity`. + * + * `data` can be a hexadecimal string or a `bigint`. + */ + constructor(data) { + this.__identity__ = typeof data === "string" ? hexStringToU256(data) : data; + } + /** + * Get the algebraic type representation of the {@link Identity} type. + * @returns The algebraic type representation of the type. + */ + static getAlgebraicType() { + return AlgebraicType.Product({ elements: [{ + name: "__identity__", + algebraicType: AlgebraicType.U256 + }] }); + } + /** + * Check if two identities are equal. + */ + isEqual(other) { + return this.toHexString() === other.toHexString(); + } + /** + * Check if two identities are equal. + */ + equals(other) { + return this.isEqual(other); + } + /** + * Print the identity as a hexadecimal string. + */ + toHexString() { + return u256ToHexString(this.__identity__); + } + /** + * Convert the address to a Uint8Array. + */ + toUint8Array() { + return u256ToUint8Array(this.__identity__); + } + /** + * Parse an Identity from a hexadecimal string. + */ + static fromString(str) { + return new _Identity(str); + } + /** + * Zero identity (0x0000000000000000000000000000000000000000000000000000000000000000) + */ + static zero() { + return new _Identity(0n); + } + toString() { + return this.toHexString(); + } +}; +var SERIALIZERS = /* @__PURE__ */ new Map(); +var DESERIALIZERS = /* @__PURE__ */ new Map(); +var AlgebraicType = { + Ref: (value) => ({ + tag: "Ref", + value + }), + Sum: (value) => ({ + tag: "Sum", + value + }), + Product: (value) => ({ + tag: "Product", + value + }), + Array: (value) => ({ + tag: "Array", + value + }), + String: { tag: "String" }, + Bool: { tag: "Bool" }, + I8: { tag: "I8" }, + U8: { tag: "U8" }, + I16: { tag: "I16" }, + U16: { tag: "U16" }, + I32: { tag: "I32" }, + U32: { tag: "U32" }, + I64: { tag: "I64" }, + U64: { tag: "U64" }, + I128: { tag: "I128" }, + U128: { tag: "U128" }, + I256: { tag: "I256" }, + U256: { tag: "U256" }, + F32: { tag: "F32" }, + F64: { tag: "F64" }, + makeSerializer(ty, typespace) { + if (ty.tag === "Ref") { + if (!typespace) throw new Error("cannot serialize refs without a typespace"); + while (ty.tag === "Ref") ty = typespace.types[ty.value]; + } + switch (ty.tag) { + case "Product": return ProductType.makeSerializer(ty.value, typespace); + case "Sum": return SumType.makeSerializer(ty.value, typespace); + case "Array": if (ty.value.tag === "U8") return serializeUint8Array; + else { + const serialize = AlgebraicType.makeSerializer(ty.value, typespace); + return (writer, value) => { + writer.writeU32(value.length); + for (const elem of value) serialize(writer, elem); + }; + } + default: return primitiveSerializers[ty.tag]; + } + }, + serializeValue(writer, ty, value, typespace) { + AlgebraicType.makeSerializer(ty, typespace)(writer, value); + }, + makeDeserializer(ty, typespace) { + if (ty.tag === "Ref") { + if (!typespace) throw new Error("cannot deserialize refs without a typespace"); + while (ty.tag === "Ref") ty = typespace.types[ty.value]; + } + switch (ty.tag) { + case "Product": return ProductType.makeDeserializer(ty.value, typespace); + case "Sum": return SumType.makeDeserializer(ty.value, typespace); + case "Array": if (ty.value.tag === "U8") return deserializeUint8Array; + else { + const deserialize = AlgebraicType.makeDeserializer(ty.value, typespace); + return (reader) => { + const length = reader.readU32(); + const result = Array(length); + for (let i = 0; i < length; i++) result[i] = deserialize(reader); + return result; + }; + } + default: return primitiveDeserializers[ty.tag]; + } + }, + deserializeValue(reader, ty, typespace) { + return AlgebraicType.makeDeserializer(ty, typespace)(reader); + }, + intoMapKey: function(ty, value) { + switch (ty.tag) { + case "U8": + case "U16": + case "U32": + case "U64": + case "U128": + case "U256": + case "I8": + case "I16": + case "I32": + case "I64": + case "I128": + case "I256": + case "F32": + case "F64": + case "String": + case "Bool": return value; + case "Product": return ProductType.intoMapKey(ty.value, value); + default: { + const writer = new BinaryWriter(10); + AlgebraicType.serializeValue(writer, ty, value); + return writer.toBase64(); + } + } + } +}; +function bindCall(f) { + return Function.prototype.call.bind(f); +} +var primitiveSerializers = { + Bool: bindCall(BinaryWriter.prototype.writeBool), + I8: bindCall(BinaryWriter.prototype.writeI8), + U8: bindCall(BinaryWriter.prototype.writeU8), + I16: bindCall(BinaryWriter.prototype.writeI16), + U16: bindCall(BinaryWriter.prototype.writeU16), + I32: bindCall(BinaryWriter.prototype.writeI32), + U32: bindCall(BinaryWriter.prototype.writeU32), + I64: bindCall(BinaryWriter.prototype.writeI64), + U64: bindCall(BinaryWriter.prototype.writeU64), + I128: bindCall(BinaryWriter.prototype.writeI128), + U128: bindCall(BinaryWriter.prototype.writeU128), + I256: bindCall(BinaryWriter.prototype.writeI256), + U256: bindCall(BinaryWriter.prototype.writeU256), + F32: bindCall(BinaryWriter.prototype.writeF32), + F64: bindCall(BinaryWriter.prototype.writeF64), + String: bindCall(BinaryWriter.prototype.writeString) +}; +Object.freeze(primitiveSerializers); +var serializeUint8Array = bindCall(BinaryWriter.prototype.writeUInt8Array); +var primitiveDeserializers = { + Bool: bindCall(BinaryReader.prototype.readBool), + I8: bindCall(BinaryReader.prototype.readI8), + U8: bindCall(BinaryReader.prototype.readU8), + I16: bindCall(BinaryReader.prototype.readI16), + U16: bindCall(BinaryReader.prototype.readU16), + I32: bindCall(BinaryReader.prototype.readI32), + U32: bindCall(BinaryReader.prototype.readU32), + I64: bindCall(BinaryReader.prototype.readI64), + U64: bindCall(BinaryReader.prototype.readU64), + I128: bindCall(BinaryReader.prototype.readI128), + U128: bindCall(BinaryReader.prototype.readU128), + I256: bindCall(BinaryReader.prototype.readI256), + U256: bindCall(BinaryReader.prototype.readU256), + F32: bindCall(BinaryReader.prototype.readF32), + F64: bindCall(BinaryReader.prototype.readF64), + String: bindCall(BinaryReader.prototype.readString) +}; +Object.freeze(primitiveDeserializers); +var deserializeUint8Array = bindCall(BinaryReader.prototype.readUInt8Array); +var primitiveSizes = { + Bool: 1, + I8: 1, + U8: 1, + I16: 2, + U16: 2, + I32: 4, + U32: 4, + I64: 8, + U64: 8, + I128: 16, + U128: 16, + I256: 32, + U256: 32, + F32: 4, + F64: 8 +}; +var fixedSizePrimitives = new Set(Object.keys(primitiveSizes)); +var isFixedSizeProduct = (ty) => ty.elements.every(({ algebraicType }) => fixedSizePrimitives.has(algebraicType.tag)); +var productSize = (ty) => ty.elements.reduce((acc, { algebraicType }) => acc + primitiveSizes[algebraicType.tag], 0); +var primitiveJSName = { + Bool: "Uint8", + I8: "Int8", + U8: "Uint8", + I16: "Int16", + U16: "Uint16", + I32: "Int32", + U32: "Uint32", + I64: "BigInt64", + U64: "BigUint64", + F32: "Float32", + F64: "Float64" +}; +var specialProductDeserializers = { + __time_duration_micros__: (reader) => new TimeDuration(reader.readI64()), + __timestamp_micros_since_unix_epoch__: (reader) => new Timestamp(reader.readI64()), + __identity__: (reader) => new Identity(reader.readU256()), + __connection_id__: (reader) => new ConnectionId(reader.readU128()), + __uuid__: (reader) => new Uuid(reader.readU128()) +}; +Object.freeze(specialProductDeserializers); +var unitDeserializer = () => ({}); +var getElementInitializer = (element) => { + let init; + switch (element.algebraicType.tag) { + case "String": + init = "''"; + break; + case "Bool": + init = "false"; + break; + case "I8": + case "U8": + case "I16": + case "U16": + case "I32": + case "U32": + init = "0"; + break; + case "I64": + case "U64": + case "I128": + case "U128": + case "I256": + case "U256": + init = "0n"; + break; + case "F32": + case "F64": + init = "0.0"; + break; + default: init = "undefined"; + } + return `${element.name}: ${init}`; +}; +var ProductType = { + makeSerializer(ty, typespace) { + let serializer = SERIALIZERS.get(ty); + if (serializer != null) return serializer; + if (isFixedSizeProduct(ty)) { + const body2 = `"use strict"; +writer.expandBuffer(${productSize(ty)}); +const view = writer.view; +${ty.elements.map(({ name, algebraicType: { tag } }) => tag in primitiveJSName ? `view.set${primitiveJSName[tag]}(writer.offset, value.${name}, ${primitiveSizes[tag] > 1 ? "true" : ""}); +writer.offset += ${primitiveSizes[tag]};` : `writer.write${tag}(value.${name});`).join("\n")}`; + serializer = Function("writer", "value", body2); + SERIALIZERS.set(ty, serializer); + return serializer; + } + const serializers = {}; + const body = "\"use strict\";\n" + ty.elements.map((element) => `this.${element.name}(writer, value.${element.name});`).join("\n"); + serializer = Function("writer", "value", body).bind(serializers); + SERIALIZERS.set(ty, serializer); + for (const { name, algebraicType } of ty.elements) serializers[name] = AlgebraicType.makeSerializer(algebraicType, typespace); + Object.freeze(serializers); + return serializer; + }, + serializeValue(writer, ty, value, typespace) { + ProductType.makeSerializer(ty, typespace)(writer, value); + }, + makeDeserializer(ty, typespace) { + switch (ty.elements.length) { + case 0: return unitDeserializer; + case 1: { + const fieldName = ty.elements[0].name; + if (hasOwn(specialProductDeserializers, fieldName)) return specialProductDeserializers[fieldName]; + } + } + let deserializer = DESERIALIZERS.get(ty); + if (deserializer != null) return deserializer; + if (isFixedSizeProduct(ty)) { + const body = `"use strict"; +const result = { ${ty.elements.map(getElementInitializer).join(", ")} }; +const view = reader.view; +${ty.elements.map(({ name, algebraicType: { tag } }) => tag in primitiveJSName ? tag === "Bool" ? `result.${name} = view.getUint8(reader.offset) !== 0; +reader.offset += 1;` : `result.${name} = view.get${primitiveJSName[tag]}(reader.offset, ${primitiveSizes[tag] > 1 ? "true" : ""}); +reader.offset += ${primitiveSizes[tag]};` : `result.${name} = reader.read${tag}();`).join("\n")} +return result;`; + deserializer = Function("reader", body); + DESERIALIZERS.set(ty, deserializer); + return deserializer; + } + const deserializers = {}; + deserializer = Function("reader", `"use strict"; +const result = { ${ty.elements.map(getElementInitializer).join(", ")} }; +${ty.elements.map(({ name }) => `result.${name} = this.${name}(reader);`).join("\n")} +return result;`).bind(deserializers); + DESERIALIZERS.set(ty, deserializer); + for (const { name, algebraicType } of ty.elements) deserializers[name] = AlgebraicType.makeDeserializer(algebraicType, typespace); + Object.freeze(deserializers); + return deserializer; + }, + deserializeValue(reader, ty, typespace) { + return ProductType.makeDeserializer(ty, typespace)(reader); + }, + intoMapKey(ty, value) { + if (ty.elements.length === 1) { + const fieldName = ty.elements[0].name; + if (hasOwn(specialProductDeserializers, fieldName)) return value[fieldName]; + } + const writer = new BinaryWriter(10); + AlgebraicType.serializeValue(writer, AlgebraicType.Product(ty), value); + return writer.toBase64(); + } +}; +var SumType = { + makeSerializer(ty, typespace) { + if (ty.variants.length == 2 && ty.variants[0].name === "some" && ty.variants[1].name === "none") { + const serialize = AlgebraicType.makeSerializer(ty.variants[0].algebraicType, typespace); + return (writer, value) => { + if (value !== null && value !== void 0) { + writer.writeByte(0); + serialize(writer, value); + } else writer.writeByte(1); + }; + } else if (ty.variants.length == 2 && ty.variants[0].name === "ok" && ty.variants[1].name === "err") { + const serializeOk = AlgebraicType.makeSerializer(ty.variants[0].algebraicType, typespace); + const serializeErr = AlgebraicType.makeSerializer(ty.variants[0].algebraicType, typespace); + return (writer, value) => { + if ("ok" in value) { + writer.writeU8(0); + serializeOk(writer, value.ok); + } else if ("err" in value) { + writer.writeU8(1); + serializeErr(writer, value.err); + } else throw new TypeError("could not serialize result: object had neither a `ok` nor an `err` field"); + }; + } else { + let serializer = SERIALIZERS.get(ty); + if (serializer != null) return serializer; + const serializers = {}; + const body = `switch (value.tag) { +${ty.variants.map(({ name }, i) => ` case ${JSON.stringify(name)}: + writer.writeByte(${i}); + return this.${name}(writer, value.value);`).join("\n")} + default: + throw new TypeError( + \`Could not serialize sum type; unknown tag \${value.tag}\` + ) +} +`; + serializer = Function("writer", "value", body).bind(serializers); + SERIALIZERS.set(ty, serializer); + for (const { name, algebraicType } of ty.variants) serializers[name] = AlgebraicType.makeSerializer(algebraicType, typespace); + Object.freeze(serializers); + return serializer; + } + }, + serializeValue(writer, ty, value, typespace) { + SumType.makeSerializer(ty, typespace)(writer, value); + }, + makeDeserializer(ty, typespace) { + if (ty.variants.length == 2 && ty.variants[0].name === "some" && ty.variants[1].name === "none") { + const deserialize = AlgebraicType.makeDeserializer(ty.variants[0].algebraicType, typespace); + return (reader) => { + const tag = reader.readU8(); + if (tag === 0) return deserialize(reader); + else if (tag === 1) return; + else throw `Can't deserialize an option type, couldn't find ${tag} tag`; + }; + } else if (ty.variants.length == 2 && ty.variants[0].name === "ok" && ty.variants[1].name === "err") { + const deserializeOk = AlgebraicType.makeDeserializer(ty.variants[0].algebraicType, typespace); + const deserializeErr = AlgebraicType.makeDeserializer(ty.variants[1].algebraicType, typespace); + return (reader) => { + const tag = reader.readByte(); + if (tag === 0) return { ok: deserializeOk(reader) }; + else if (tag === 1) return { err: deserializeErr(reader) }; + else throw `Can't deserialize a result type, couldn't find ${tag} tag`; + }; + } else { + let deserializer = DESERIALIZERS.get(ty); + if (deserializer != null) return deserializer; + const deserializers = {}; + deserializer = Function("reader", `switch (reader.readU8()) { +${ty.variants.map(({ name }, i) => `case ${i}: return { tag: ${JSON.stringify(name)}, value: this.${name}(reader) };`).join("\n")} }`).bind(deserializers); + DESERIALIZERS.set(ty, deserializer); + for (const { name, algebraicType } of ty.variants) deserializers[name] = AlgebraicType.makeDeserializer(algebraicType, typespace); + Object.freeze(deserializers); + return deserializer; + } + }, + deserializeValue(reader, ty, typespace) { + return SumType.makeDeserializer(ty, typespace)(reader); + } +}; +var Option = { getAlgebraicType(innerType) { + return AlgebraicType.Sum({ variants: [{ + name: "some", + algebraicType: innerType + }, { + name: "none", + algebraicType: AlgebraicType.Product({ elements: [] }) + }] }); +} }; +var Result = { getAlgebraicType(okType, errType) { + return AlgebraicType.Sum({ variants: [{ + name: "ok", + algebraicType: okType + }, { + name: "err", + algebraicType: errType + }] }); +} }; +var ScheduleAt = { + interval(value) { + return Interval(value); + }, + time(value) { + return Time(value); + }, + getAlgebraicType() { + return AlgebraicType.Sum({ variants: [{ + name: "Interval", + algebraicType: TimeDuration.getAlgebraicType() + }, { + name: "Time", + algebraicType: Timestamp.getAlgebraicType() + }] }); + }, + isScheduleAt(algebraicType) { + if (algebraicType.tag !== "Sum") return false; + const variants = algebraicType.value.variants; + if (variants.length !== 2) return false; + const intervalVariant = variants.find((v) => v.name === "Interval"); + const timeVariant = variants.find((v) => v.name === "Time"); + if (!intervalVariant || !timeVariant) return false; + return TimeDuration.isTimeDuration(intervalVariant.algebraicType) && Timestamp.isTimestamp(timeVariant.algebraicType); + } +}; +var Interval = (micros) => ({ + tag: "Interval", + value: new TimeDuration(micros) +}); +var Time = (microsSinceUnixEpoch) => ({ + tag: "Time", + value: new Timestamp(microsSinceUnixEpoch) +}); +var schedule_at_default = ScheduleAt; +function set(x, t2) { + return { + ...x, + ...t2 + }; +} +var TypeBuilder = class { + /** + * The TypeScript phantom type. This is not stored at runtime, + * but is visible to the compiler + */ + type; + /** + * The SpacetimeDB algebraic type (run‑time value). In addition to storing + * the runtime representation of the `AlgebraicType`, it also captures + * the TypeScript type information of the `AlgebraicType`. That is to say + * the value is not merely an `AlgebraicType`, but is constructed to be + * the corresponding concrete `AlgebraicType` for the TypeScript type `Type`. + * + * e.g. `string` corresponds to `AlgebraicType.String` + */ + algebraicType; + constructor(algebraicType) { + this.algebraicType = algebraicType; + } + optional() { + return new OptionBuilder(this); + } + serialize(writer, value) { + (this.serialize = AlgebraicType.makeSerializer(this.algebraicType))(writer, value); + } + deserialize(reader) { + return (this.deserialize = AlgebraicType.makeDeserializer(this.algebraicType))(reader); + } +}; +var U8Builder = class extends TypeBuilder { + constructor() { + super(AlgebraicType.U8); + } + index(algorithm = "btree") { + return new U8ColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new U8ColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new U8ColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new U8ColumnBuilder(this, set(defaultMetadata, { isAutoIncrement: true })); + } + default(value) { + return new U8ColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new U8ColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var U16Builder = class extends TypeBuilder { + constructor() { + super(AlgebraicType.U16); + } + index(algorithm = "btree") { + return new U16ColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new U16ColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new U16ColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new U16ColumnBuilder(this, set(defaultMetadata, { isAutoIncrement: true })); + } + default(value) { + return new U16ColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new U16ColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var U32Builder = class extends TypeBuilder { + constructor() { + super(AlgebraicType.U32); + } + index(algorithm = "btree") { + return new U32ColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new U32ColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new U32ColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new U32ColumnBuilder(this, set(defaultMetadata, { isAutoIncrement: true })); + } + default(value) { + return new U32ColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new U32ColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var U64Builder = class extends TypeBuilder { + constructor() { + super(AlgebraicType.U64); + } + index(algorithm = "btree") { + return new U64ColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new U64ColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new U64ColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new U64ColumnBuilder(this, set(defaultMetadata, { isAutoIncrement: true })); + } + default(value) { + return new U64ColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new U64ColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var U128Builder = class extends TypeBuilder { + constructor() { + super(AlgebraicType.U128); + } + index(algorithm = "btree") { + return new U128ColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new U128ColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new U128ColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new U128ColumnBuilder(this, set(defaultMetadata, { isAutoIncrement: true })); + } + default(value) { + return new U128ColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new U128ColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var U256Builder = class extends TypeBuilder { + constructor() { + super(AlgebraicType.U256); + } + index(algorithm = "btree") { + return new U256ColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new U256ColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new U256ColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new U256ColumnBuilder(this, set(defaultMetadata, { isAutoIncrement: true })); + } + default(value) { + return new U256ColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new U256ColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var I8Builder = class extends TypeBuilder { + constructor() { + super(AlgebraicType.I8); + } + index(algorithm = "btree") { + return new I8ColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new I8ColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new I8ColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new I8ColumnBuilder(this, set(defaultMetadata, { isAutoIncrement: true })); + } + default(value) { + return new I8ColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new I8ColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var I16Builder = class extends TypeBuilder { + constructor() { + super(AlgebraicType.I16); + } + index(algorithm = "btree") { + return new I16ColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new I16ColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new I16ColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new I16ColumnBuilder(this, set(defaultMetadata, { isAutoIncrement: true })); + } + default(value) { + return new I16ColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new I16ColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var I32Builder = class extends TypeBuilder { + constructor() { + super(AlgebraicType.I32); + } + index(algorithm = "btree") { + return new I32ColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new I32ColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new I32ColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new I32ColumnBuilder(this, set(defaultMetadata, { isAutoIncrement: true })); + } + default(value) { + return new I32ColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new I32ColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var I64Builder = class extends TypeBuilder { + constructor() { + super(AlgebraicType.I64); + } + index(algorithm = "btree") { + return new I64ColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new I64ColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new I64ColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new I64ColumnBuilder(this, set(defaultMetadata, { isAutoIncrement: true })); + } + default(value) { + return new I64ColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new I64ColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var I128Builder = class extends TypeBuilder { + constructor() { + super(AlgebraicType.I128); + } + index(algorithm = "btree") { + return new I128ColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new I128ColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new I128ColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new I128ColumnBuilder(this, set(defaultMetadata, { isAutoIncrement: true })); + } + default(value) { + return new I128ColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new I128ColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var I256Builder = class extends TypeBuilder { + constructor() { + super(AlgebraicType.I256); + } + index(algorithm = "btree") { + return new I256ColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new I256ColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new I256ColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new I256ColumnBuilder(this, set(defaultMetadata, { isAutoIncrement: true })); + } + default(value) { + return new I256ColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new I256ColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var F32Builder = class extends TypeBuilder { + constructor() { + super(AlgebraicType.F32); + } + default(value) { + return new F32ColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new F32ColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var F64Builder = class extends TypeBuilder { + constructor() { + super(AlgebraicType.F64); + } + default(value) { + return new F64ColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new F64ColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var BoolBuilder = class extends TypeBuilder { + constructor() { + super(AlgebraicType.Bool); + } + index(algorithm = "btree") { + return new BoolColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new BoolColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new BoolColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + default(value) { + return new BoolColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new BoolColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var StringBuilder = class extends TypeBuilder { + constructor() { + super(AlgebraicType.String); + } + index(algorithm = "btree") { + return new StringColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new StringColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new StringColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + default(value) { + return new StringColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new StringColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var ArrayBuilder = class extends TypeBuilder { + element; + constructor(element) { + super(AlgebraicType.Array(element.algebraicType)); + this.element = element; + } + default(value) { + return new ArrayColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new ArrayColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var ByteArrayBuilder = class extends TypeBuilder { + constructor() { + super(AlgebraicType.Array(AlgebraicType.U8)); + } + default(value) { + return new ByteArrayColumnBuilder(set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new ByteArrayColumnBuilder(set(defaultMetadata, { name })); + } +}; +var OptionBuilder = class extends TypeBuilder { + value; + constructor(value) { + super(Option.getAlgebraicType(value.algebraicType)); + this.value = value; + } + default(value) { + return new OptionColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new OptionColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var ProductBuilder = class extends TypeBuilder { + typeName; + elements; + constructor(elements, name) { + function elementsArrayFromElementsObj(obj) { + return Object.keys(obj).map((key) => ({ + name: key, + get algebraicType() { + return obj[key].algebraicType; + } + })); + } + super(AlgebraicType.Product({ elements: elementsArrayFromElementsObj(elements) })); + this.typeName = name; + this.elements = elements; + } + default(value) { + return new ProductColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new ProductColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var ResultBuilder = class extends TypeBuilder { + ok; + err; + constructor(ok, err) { + super(Result.getAlgebraicType(ok.algebraicType, err.algebraicType)); + this.ok = ok; + this.err = err; + } + default(value) { + return new ResultColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } +}; +var UnitBuilder = class extends TypeBuilder { + constructor() { + super({ + tag: "Product", + value: { elements: [] } + }); + } +}; +var RowBuilder = class extends TypeBuilder { + row; + typeName; + constructor(row, name) { + const mappedRow = Object.fromEntries(Object.entries(row).map(([colName, builder]) => [colName, builder instanceof ColumnBuilder ? builder : new ColumnBuilder(builder, {})])); + const elements = Object.keys(mappedRow).map((name2) => ({ + name: name2, + get algebraicType() { + return mappedRow[name2].typeBuilder.algebraicType; + } + })); + super(AlgebraicType.Product({ elements })); + this.row = mappedRow; + this.typeName = name; + } +}; +var SumBuilderImpl = class extends TypeBuilder { + variants; + typeName; + constructor(variants, name) { + function variantsArrayFromVariantsObj(variants2) { + return Object.keys(variants2).map((key) => ({ + name: key, + get algebraicType() { + return variants2[key].algebraicType; + } + })); + } + super(AlgebraicType.Sum({ variants: variantsArrayFromVariantsObj(variants) })); + this.variants = variants; + this.typeName = name; + for (const key of Object.keys(variants)) { + const desc = Object.getOwnPropertyDescriptor(variants, key); + const isAccessor = !!desc && (typeof desc.get === "function" || typeof desc.set === "function"); + let isUnit2 = false; + if (!isAccessor) isUnit2 = variants[key] instanceof UnitBuilder; + if (isUnit2) { + const constant = this.create(key); + Object.defineProperty(this, key, { + value: constant, + writable: false, + enumerable: true, + configurable: false + }); + } else { + const fn = ((value) => this.create(key, value)); + Object.defineProperty(this, key, { + value: fn, + writable: false, + enumerable: true, + configurable: false + }); + } + } + } + create(tag, value) { + return value === void 0 ? { tag } : { + tag, + value + }; + } + default(value) { + return new SumColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new SumColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var SumBuilder = SumBuilderImpl; +var SimpleSumBuilderImpl = class extends SumBuilderImpl { + index(algorithm = "btree") { + return new SimpleSumColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + primaryKey() { + return new SimpleSumColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } +}; +var ScheduleAtBuilder = class extends TypeBuilder { + constructor() { + super(schedule_at_default.getAlgebraicType()); + } + default(value) { + return new ScheduleAtColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new ScheduleAtColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var IdentityBuilder = class extends TypeBuilder { + constructor() { + super(Identity.getAlgebraicType()); + } + index(algorithm = "btree") { + return new IdentityColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new IdentityColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new IdentityColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new IdentityColumnBuilder(this, set(defaultMetadata, { isAutoIncrement: true })); + } + default(value) { + return new IdentityColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new IdentityColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var ConnectionIdBuilder = class extends TypeBuilder { + constructor() { + super(ConnectionId.getAlgebraicType()); + } + index(algorithm = "btree") { + return new ConnectionIdColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new ConnectionIdColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new ConnectionIdColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new ConnectionIdColumnBuilder(this, set(defaultMetadata, { isAutoIncrement: true })); + } + default(value) { + return new ConnectionIdColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new ConnectionIdColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var TimestampBuilder = class extends TypeBuilder { + constructor() { + super(Timestamp.getAlgebraicType()); + } + index(algorithm = "btree") { + return new TimestampColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new TimestampColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new TimestampColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new TimestampColumnBuilder(this, set(defaultMetadata, { isAutoIncrement: true })); + } + default(value) { + return new TimestampColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new TimestampColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var TimeDurationBuilder = class extends TypeBuilder { + constructor() { + super(TimeDuration.getAlgebraicType()); + } + index(algorithm = "btree") { + return new TimeDurationColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new TimeDurationColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new TimeDurationColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new TimeDurationColumnBuilder(this, set(defaultMetadata, { isAutoIncrement: true })); + } + default(value) { + return new TimeDurationColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new TimeDurationColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var UuidBuilder = class extends TypeBuilder { + constructor() { + super(Uuid.getAlgebraicType()); + } + index(algorithm = "btree") { + return new UuidColumnBuilder(this, set(defaultMetadata, { indexType: algorithm })); + } + unique() { + return new UuidColumnBuilder(this, set(defaultMetadata, { isUnique: true })); + } + primaryKey() { + return new UuidColumnBuilder(this, set(defaultMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new UuidColumnBuilder(this, set(defaultMetadata, { isAutoIncrement: true })); + } + default(value) { + return new UuidColumnBuilder(this, set(defaultMetadata, { defaultValue: value })); + } + name(name) { + return new UuidColumnBuilder(this, set(defaultMetadata, { name })); + } +}; +var defaultMetadata = {}; +var ColumnBuilder = class { + typeBuilder; + columnMetadata; + constructor(typeBuilder, metadata) { + this.typeBuilder = typeBuilder; + this.columnMetadata = metadata; + } + serialize(writer, value) { + this.typeBuilder.serialize(writer, value); + } + deserialize(reader) { + return this.typeBuilder.deserialize(reader); + } +}; +var U8ColumnBuilder = class _U8ColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _U8ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _U8ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _U8ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new _U8ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isAutoIncrement: true })); + } + default(value) { + return new _U8ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _U8ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var U16ColumnBuilder = class _U16ColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _U16ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _U16ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _U16ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new _U16ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isAutoIncrement: true })); + } + default(value) { + return new _U16ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _U16ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var U32ColumnBuilder = class _U32ColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _U32ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _U32ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _U32ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new _U32ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isAutoIncrement: true })); + } + default(value) { + return new _U32ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _U32ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var U64ColumnBuilder = class _U64ColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _U64ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _U64ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _U64ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new _U64ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isAutoIncrement: true })); + } + default(value) { + return new _U64ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _U64ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var U128ColumnBuilder = class _U128ColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _U128ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _U128ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _U128ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new _U128ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isAutoIncrement: true })); + } + default(value) { + return new _U128ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _U128ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var U256ColumnBuilder = class _U256ColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _U256ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _U256ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _U256ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new _U256ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isAutoIncrement: true })); + } + default(value) { + return new _U256ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _U256ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var I8ColumnBuilder = class _I8ColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _I8ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _I8ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _I8ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new _I8ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isAutoIncrement: true })); + } + default(value) { + return new _I8ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _I8ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var I16ColumnBuilder = class _I16ColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _I16ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _I16ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _I16ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new _I16ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isAutoIncrement: true })); + } + default(value) { + return new _I16ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _I16ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var I32ColumnBuilder = class _I32ColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _I32ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _I32ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _I32ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new _I32ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isAutoIncrement: true })); + } + default(value) { + return new _I32ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _I32ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var I64ColumnBuilder = class _I64ColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _I64ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _I64ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _I64ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new _I64ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isAutoIncrement: true })); + } + default(value) { + return new _I64ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _I64ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var I128ColumnBuilder = class _I128ColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _I128ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _I128ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _I128ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new _I128ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isAutoIncrement: true })); + } + default(value) { + return new _I128ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _I128ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var I256ColumnBuilder = class _I256ColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _I256ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _I256ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _I256ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + autoInc() { + return new _I256ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isAutoIncrement: true })); + } + default(value) { + return new _I256ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _I256ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var F32ColumnBuilder = class _F32ColumnBuilder extends ColumnBuilder { + default(value) { + return new _F32ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _F32ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var F64ColumnBuilder = class _F64ColumnBuilder extends ColumnBuilder { + default(value) { + return new _F64ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _F64ColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var BoolColumnBuilder = class _BoolColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _BoolColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _BoolColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _BoolColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + default(value) { + return new _BoolColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _BoolColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var StringColumnBuilder = class _StringColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _StringColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _StringColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _StringColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + default(value) { + return new _StringColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _StringColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var ArrayColumnBuilder = class _ArrayColumnBuilder extends ColumnBuilder { + default(value) { + return new _ArrayColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _ArrayColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var ByteArrayColumnBuilder = class _ByteArrayColumnBuilder extends ColumnBuilder { + constructor(metadata) { + super(new TypeBuilder(AlgebraicType.Array(AlgebraicType.U8)), metadata); + } + default(value) { + return new _ByteArrayColumnBuilder(set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _ByteArrayColumnBuilder(set(this.columnMetadata, { name })); + } +}; +var OptionColumnBuilder = class _OptionColumnBuilder extends ColumnBuilder { + default(value) { + return new _OptionColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _OptionColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var ResultColumnBuilder = class _ResultColumnBuilder extends ColumnBuilder { + constructor(typeBuilder, metadata) { + super(typeBuilder, metadata); + } + default(value) { + return new _ResultColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } +}; +var ProductColumnBuilder = class _ProductColumnBuilder extends ColumnBuilder { + default(value) { + return new _ProductColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _ProductColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var SumColumnBuilder = class _SumColumnBuilder extends ColumnBuilder { + default(value) { + return new _SumColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _SumColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var SimpleSumColumnBuilder = class _SimpleSumColumnBuilder extends SumColumnBuilder { + index(algorithm = "btree") { + return new _SimpleSumColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + primaryKey() { + return new _SimpleSumColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } +}; +var ScheduleAtColumnBuilder = class _ScheduleAtColumnBuilder extends ColumnBuilder { + default(value) { + return new _ScheduleAtColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _ScheduleAtColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var IdentityColumnBuilder = class _IdentityColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _IdentityColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _IdentityColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _IdentityColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + default(value) { + return new _IdentityColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _IdentityColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var ConnectionIdColumnBuilder = class _ConnectionIdColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _ConnectionIdColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _ConnectionIdColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _ConnectionIdColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + default(value) { + return new _ConnectionIdColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _ConnectionIdColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var TimestampColumnBuilder = class _TimestampColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _TimestampColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _TimestampColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _TimestampColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + default(value) { + return new _TimestampColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _TimestampColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var TimeDurationColumnBuilder = class _TimeDurationColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _TimeDurationColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _TimeDurationColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _TimeDurationColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + default(value) { + return new _TimeDurationColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _TimeDurationColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var UuidColumnBuilder = class _UuidColumnBuilder extends ColumnBuilder { + index(algorithm = "btree") { + return new _UuidColumnBuilder(this.typeBuilder, set(this.columnMetadata, { indexType: algorithm })); + } + unique() { + return new _UuidColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isUnique: true })); + } + primaryKey() { + return new _UuidColumnBuilder(this.typeBuilder, set(this.columnMetadata, { isPrimaryKey: true })); + } + default(value) { + return new _UuidColumnBuilder(this.typeBuilder, set(this.columnMetadata, { defaultValue: value })); + } + name(name) { + return new _UuidColumnBuilder(this.typeBuilder, set(this.columnMetadata, { name })); + } +}; +var RefBuilder = class extends TypeBuilder { + ref; + /** The phantom type of the pointee of this ref. */ + __spacetimeType; + constructor(ref) { + super(AlgebraicType.Ref(ref)); + this.ref = ref; + } +}; +var enumImpl = ((nameOrObj, maybeObj) => { + let obj = nameOrObj; + let name = void 0; + if (typeof nameOrObj === "string") { + if (!maybeObj) throw new TypeError("When providing a name, you must also provide the variants object or array."); + obj = maybeObj; + name = nameOrObj; + } + if (Array.isArray(obj)) { + const simpleVariantsObj = {}; + for (const variant of obj) simpleVariantsObj[variant] = new UnitBuilder(); + return new SimpleSumBuilderImpl(simpleVariantsObj, name); + } + return new SumBuilder(obj, name); +}); +var t = { + bool: () => new BoolBuilder(), + string: () => new StringBuilder(), + number: () => new F64Builder(), + i8: () => new I8Builder(), + u8: () => new U8Builder(), + i16: () => new I16Builder(), + u16: () => new U16Builder(), + i32: () => new I32Builder(), + u32: () => new U32Builder(), + i64: () => new I64Builder(), + u64: () => new U64Builder(), + i128: () => new I128Builder(), + u128: () => new U128Builder(), + i256: () => new I256Builder(), + u256: () => new U256Builder(), + f32: () => new F32Builder(), + f64: () => new F64Builder(), + object: ((nameOrObj, maybeObj) => { + if (typeof nameOrObj === "string") { + if (!maybeObj) throw new TypeError("When providing a name, you must also provide the object."); + return new ProductBuilder(maybeObj, nameOrObj); + } + return new ProductBuilder(nameOrObj, void 0); + }), + row: ((nameOrObj, maybeObj) => { + const [obj, name] = typeof nameOrObj === "string" ? [maybeObj, nameOrObj] : [nameOrObj, void 0]; + return new RowBuilder(obj, name); + }), + array(e) { + return new ArrayBuilder(e); + }, + enum: enumImpl, + unit() { + return new UnitBuilder(); + }, + lazy(thunk) { + let cached = null; + const get = () => cached ??= thunk(); + return new Proxy({}, { + get(_t, prop, recv) { + const target = get(); + const val = Reflect.get(target, prop, recv); + return typeof val === "function" ? val.bind(target) : val; + }, + set(_t, prop, value, recv) { + return Reflect.set(get(), prop, value, recv); + }, + has(_t, prop) { + return prop in get(); + }, + ownKeys() { + return Reflect.ownKeys(get()); + }, + getOwnPropertyDescriptor(_t, prop) { + return Object.getOwnPropertyDescriptor(get(), prop); + }, + getPrototypeOf() { + return Object.getPrototypeOf(get()); + } + }); + }, + scheduleAt: () => { + return new ScheduleAtBuilder(); + }, + option(value) { + return new OptionBuilder(value); + }, + result(ok, err) { + return new ResultBuilder(ok, err); + }, + identity: () => { + return new IdentityBuilder(); + }, + connectionId: () => { + return new ConnectionIdBuilder(); + }, + timestamp: () => { + return new TimestampBuilder(); + }, + timeDuration: () => { + return new TimeDurationBuilder(); + }, + uuid: () => { + return new UuidBuilder(); + }, + byteArray: () => { + return new ByteArrayBuilder(); + } +}; +var AlgebraicType2 = t.enum("AlgebraicType", { + Ref: t.u32(), + get Sum() { + return SumType2; + }, + get Product() { + return ProductType2; + }, + get Array() { + return AlgebraicType2; + }, + String: t.unit(), + Bool: t.unit(), + I8: t.unit(), + U8: t.unit(), + I16: t.unit(), + U16: t.unit(), + I32: t.unit(), + U32: t.unit(), + I64: t.unit(), + U64: t.unit(), + I128: t.unit(), + U128: t.unit(), + I256: t.unit(), + U256: t.unit(), + F32: t.unit(), + F64: t.unit() +}); +var CaseConversionPolicy = t.enum("CaseConversionPolicy", { + None: t.unit(), + SnakeCase: t.unit() +}); +var ExplicitNameEntry = t.enum("ExplicitNameEntry", { + get Table() { + return NameMapping; + }, + get Function() { + return NameMapping; + }, + get Index() { + return NameMapping; + } +}); +var ExplicitNames = t.object("ExplicitNames", { get entries() { + return t.array(ExplicitNameEntry); +} }); +var FunctionVisibility = t.enum("FunctionVisibility", { + Private: t.unit(), + ClientCallable: t.unit() +}); +var HttpHeaderPair = t.object("HttpHeaderPair", { + name: t.string(), + value: t.byteArray() +}); +var HttpHeaders = t.object("HttpHeaders", { get entries() { + return t.array(HttpHeaderPair); +} }); +var HttpMethod = t.enum("HttpMethod", { + Get: t.unit(), + Head: t.unit(), + Post: t.unit(), + Put: t.unit(), + Delete: t.unit(), + Connect: t.unit(), + Options: t.unit(), + Trace: t.unit(), + Patch: t.unit(), + Extension: t.string() +}); +var HttpRequest = t.object("HttpRequest", { + get method() { + return HttpMethod; + }, + get headers() { + return HttpHeaders; + }, + timeout: t.option(t.timeDuration()), + uri: t.string(), + get version() { + return HttpVersion; + } +}); +var HttpResponse = t.object("HttpResponse", { + get headers() { + return HttpHeaders; + }, + get version() { + return HttpVersion; + }, + code: t.u16() +}); +var HttpVersion = t.enum("HttpVersion", { + Http09: t.unit(), + Http10: t.unit(), + Http11: t.unit(), + Http2: t.unit(), + Http3: t.unit() +}); +var IndexType = t.enum("IndexType", { + BTree: t.unit(), + Hash: t.unit() +}); +var Lifecycle = t.enum("Lifecycle", { + Init: t.unit(), + OnConnect: t.unit(), + OnDisconnect: t.unit() +}); +var MiscModuleExport = t.enum("MiscModuleExport", { get TypeAlias() { + return TypeAlias; +} }); +var NameMapping = t.object("NameMapping", { + sourceName: t.string(), + canonicalName: t.string() +}); +var ProductType2 = t.object("ProductType", { get elements() { + return t.array(ProductTypeElement); +} }); +var ProductTypeElement = t.object("ProductTypeElement", { + name: t.option(t.string()), + get algebraicType() { + return AlgebraicType2; + } +}); +var RawColumnDefV8 = t.object("RawColumnDefV8", { + colName: t.string(), + get colType() { + return AlgebraicType2; + } +}); +var RawColumnDefaultValueV10 = t.object("RawColumnDefaultValueV10", { + colId: t.u16(), + value: t.byteArray() +}); +var RawColumnDefaultValueV9 = t.object("RawColumnDefaultValueV9", { + table: t.string(), + colId: t.u16(), + value: t.byteArray() +}); +var RawConstraintDataV9 = t.enum("RawConstraintDataV9", { get Unique() { + return RawUniqueConstraintDataV9; +} }); +var RawConstraintDefV10 = t.object("RawConstraintDefV10", { + sourceName: t.option(t.string()), + get data() { + return RawConstraintDataV9; + } +}); +var RawConstraintDefV8 = t.object("RawConstraintDefV8", { + constraintName: t.string(), + constraints: t.u8(), + columns: t.array(t.u16()) +}); +var RawConstraintDefV9 = t.object("RawConstraintDefV9", { + name: t.option(t.string()), + get data() { + return RawConstraintDataV9; + } +}); +var RawIndexAlgorithm = t.enum("RawIndexAlgorithm", { + BTree: t.array(t.u16()), + Hash: t.array(t.u16()), + Direct: t.u16() +}); +var RawIndexDefV10 = t.object("RawIndexDefV10", { + sourceName: t.option(t.string()), + accessorName: t.option(t.string()), + get algorithm() { + return RawIndexAlgorithm; + } +}); +var RawIndexDefV8 = t.object("RawIndexDefV8", { + indexName: t.string(), + isUnique: t.bool(), + get indexType() { + return IndexType; + }, + columns: t.array(t.u16()) +}); +var RawIndexDefV9 = t.object("RawIndexDefV9", { + name: t.option(t.string()), + accessorName: t.option(t.string()), + get algorithm() { + return RawIndexAlgorithm; + } +}); +var RawLifeCycleReducerDefV10 = t.object("RawLifeCycleReducerDefV10", { + get lifecycleSpec() { + return Lifecycle; + }, + functionName: t.string() +}); +var RawMiscModuleExportV9 = t.enum("RawMiscModuleExportV9", { + get ColumnDefaultValue() { + return RawColumnDefaultValueV9; + }, + get Procedure() { + return RawProcedureDefV9; + }, + get View() { + return RawViewDefV9; + } +}); +var RawModuleDef = t.enum("RawModuleDef", { + get V8BackCompat() { + return RawModuleDefV8; + }, + get V9() { + return RawModuleDefV9; + }, + get V10() { + return RawModuleDefV10; + } +}); +var RawModuleDefV10 = t.object("RawModuleDefV10", { get sections() { + return t.array(RawModuleDefV10Section); +} }); +var RawModuleDefV10Section = t.enum("RawModuleDefV10Section", { + get Typespace() { + return Typespace; + }, + get Types() { + return t.array(RawTypeDefV10); + }, + get Tables() { + return t.array(RawTableDefV10); + }, + get Reducers() { + return t.array(RawReducerDefV10); + }, + get Procedures() { + return t.array(RawProcedureDefV10); + }, + get Views() { + return t.array(RawViewDefV10); + }, + get Schedules() { + return t.array(RawScheduleDefV10); + }, + get LifeCycleReducers() { + return t.array(RawLifeCycleReducerDefV10); + }, + get RowLevelSecurity() { + return t.array(RawRowLevelSecurityDefV9); + }, + get CaseConversionPolicy() { + return CaseConversionPolicy; + }, + get ExplicitNames() { + return ExplicitNames; + } +}); +var RawModuleDefV8 = t.object("RawModuleDefV8", { + get typespace() { + return Typespace; + }, + get tables() { + return t.array(TableDesc); + }, + get reducers() { + return t.array(ReducerDef); + }, + get miscExports() { + return t.array(MiscModuleExport); + } +}); +var RawModuleDefV9 = t.object("RawModuleDefV9", { + get typespace() { + return Typespace; + }, + get tables() { + return t.array(RawTableDefV9); + }, + get reducers() { + return t.array(RawReducerDefV9); + }, + get types() { + return t.array(RawTypeDefV9); + }, + get miscExports() { + return t.array(RawMiscModuleExportV9); + }, + get rowLevelSecurity() { + return t.array(RawRowLevelSecurityDefV9); + } +}); +var RawProcedureDefV10 = t.object("RawProcedureDefV10", { + sourceName: t.string(), + get params() { + return ProductType2; + }, + get returnType() { + return AlgebraicType2; + }, + get visibility() { + return FunctionVisibility; + } +}); +var RawProcedureDefV9 = t.object("RawProcedureDefV9", { + name: t.string(), + get params() { + return ProductType2; + }, + get returnType() { + return AlgebraicType2; + } +}); +var RawReducerDefV10 = t.object("RawReducerDefV10", { + sourceName: t.string(), + get params() { + return ProductType2; + }, + get visibility() { + return FunctionVisibility; + }, + get okReturnType() { + return AlgebraicType2; + }, + get errReturnType() { + return AlgebraicType2; + } +}); +var RawReducerDefV9 = t.object("RawReducerDefV9", { + name: t.string(), + get params() { + return ProductType2; + }, + get lifecycle() { + return t.option(Lifecycle); + } +}); +var RawRowLevelSecurityDefV9 = t.object("RawRowLevelSecurityDefV9", { sql: t.string() }); +var RawScheduleDefV10 = t.object("RawScheduleDefV10", { + sourceName: t.option(t.string()), + tableName: t.string(), + scheduleAtCol: t.u16(), + functionName: t.string() +}); +var RawScheduleDefV9 = t.object("RawScheduleDefV9", { + name: t.option(t.string()), + reducerName: t.string(), + scheduledAtColumn: t.u16() +}); +var RawScopedTypeNameV10 = t.object("RawScopedTypeNameV10", { + scope: t.array(t.string()), + sourceName: t.string() +}); +var RawScopedTypeNameV9 = t.object("RawScopedTypeNameV9", { + scope: t.array(t.string()), + name: t.string() +}); +var RawSequenceDefV10 = t.object("RawSequenceDefV10", { + sourceName: t.option(t.string()), + column: t.u16(), + start: t.option(t.i128()), + minValue: t.option(t.i128()), + maxValue: t.option(t.i128()), + increment: t.i128() +}); +var RawSequenceDefV8 = t.object("RawSequenceDefV8", { + sequenceName: t.string(), + colPos: t.u16(), + increment: t.i128(), + start: t.option(t.i128()), + minValue: t.option(t.i128()), + maxValue: t.option(t.i128()), + allocated: t.i128() +}); +var RawSequenceDefV9 = t.object("RawSequenceDefV9", { + name: t.option(t.string()), + column: t.u16(), + start: t.option(t.i128()), + minValue: t.option(t.i128()), + maxValue: t.option(t.i128()), + increment: t.i128() +}); +var RawTableDefV10 = t.object("RawTableDefV10", { + sourceName: t.string(), + productTypeRef: t.u32(), + primaryKey: t.array(t.u16()), + get indexes() { + return t.array(RawIndexDefV10); + }, + get constraints() { + return t.array(RawConstraintDefV10); + }, + get sequences() { + return t.array(RawSequenceDefV10); + }, + get tableType() { + return TableType; + }, + get tableAccess() { + return TableAccess; + }, + get defaultValues() { + return t.array(RawColumnDefaultValueV10); + }, + isEvent: t.bool() +}); +var RawTableDefV8 = t.object("RawTableDefV8", { + tableName: t.string(), + get columns() { + return t.array(RawColumnDefV8); + }, + get indexes() { + return t.array(RawIndexDefV8); + }, + get constraints() { + return t.array(RawConstraintDefV8); + }, + get sequences() { + return t.array(RawSequenceDefV8); + }, + tableType: t.string(), + tableAccess: t.string(), + scheduled: t.option(t.string()) +}); +var RawTableDefV9 = t.object("RawTableDefV9", { + name: t.string(), + productTypeRef: t.u32(), + primaryKey: t.array(t.u16()), + get indexes() { + return t.array(RawIndexDefV9); + }, + get constraints() { + return t.array(RawConstraintDefV9); + }, + get sequences() { + return t.array(RawSequenceDefV9); + }, + get schedule() { + return t.option(RawScheduleDefV9); + }, + get tableType() { + return TableType; + }, + get tableAccess() { + return TableAccess; + } +}); +var RawTypeDefV10 = t.object("RawTypeDefV10", { + get sourceName() { + return RawScopedTypeNameV10; + }, + ty: t.u32(), + customOrdering: t.bool() +}); +var RawTypeDefV9 = t.object("RawTypeDefV9", { + get name() { + return RawScopedTypeNameV9; + }, + ty: t.u32(), + customOrdering: t.bool() +}); +var RawUniqueConstraintDataV9 = t.object("RawUniqueConstraintDataV9", { columns: t.array(t.u16()) }); +var RawViewDefV10 = t.object("RawViewDefV10", { + sourceName: t.string(), + index: t.u32(), + isPublic: t.bool(), + isAnonymous: t.bool(), + get params() { + return ProductType2; + }, + get returnType() { + return AlgebraicType2; + } +}); +var RawViewDefV9 = t.object("RawViewDefV9", { + name: t.string(), + index: t.u32(), + isPublic: t.bool(), + isAnonymous: t.bool(), + get params() { + return ProductType2; + }, + get returnType() { + return AlgebraicType2; + } +}); +var ReducerDef = t.object("ReducerDef", { + name: t.string(), + get args() { + return t.array(ProductTypeElement); + } +}); +var SumType2 = t.object("SumType", { get variants() { + return t.array(SumTypeVariant); +} }); +var SumTypeVariant = t.object("SumTypeVariant", { + name: t.option(t.string()), + get algebraicType() { + return AlgebraicType2; + } +}); +var TableAccess = t.enum("TableAccess", { + Public: t.unit(), + Private: t.unit() +}); +var TableDesc = t.object("TableDesc", { + get schema() { + return RawTableDefV8; + }, + data: t.u32() +}); +var TableType = t.enum("TableType", { + System: t.unit(), + User: t.unit() +}); +var TypeAlias = t.object("TypeAlias", { + name: t.string(), + ty: t.u32() +}); +var Typespace = t.object("Typespace", { get types() { + return t.array(AlgebraicType2); +} }); +var ViewResultHeader = t.enum("ViewResultHeader", { + RowData: t.unit(), + RawSql: t.string() +}); +function tableToSchema(accName, schema2, tableDef) { + const getColName = (i) => schema2.rowType.algebraicType.value.elements[i].name; + const resolvedIndexes = tableDef.indexes.map((idx) => { + const accessorName = idx.accessorName; + if (typeof accessorName !== "string" || accessorName.length === 0) throw new TypeError(`Index '${idx.sourceName ?? ""}' on table '${tableDef.sourceName}' is missing accessor name`); + const columnIds = idx.algorithm.tag === "Direct" ? [idx.algorithm.value] : idx.algorithm.value; + return { + name: accessorName, + unique: tableDef.constraints.some((c) => c.data.tag === "Unique" && c.data.value.columns.every((col) => columnIds.includes(col))), + algorithm: { + BTree: "btree", + Hash: "hash", + Direct: "direct" + }[idx.algorithm.tag], + columns: columnIds.map(getColName) + }; + }); + return { + sourceName: schema2.tableName || accName, + accessorName: accName, + columns: schema2.rowType.row, + rowType: schema2.rowSpacetimeType, + indexes: schema2.idxs, + constraints: tableDef.constraints.map((c) => ({ + name: c.sourceName, + constraint: "unique", + columns: c.data.value.columns.map(getColName) + })), + resolvedIndexes, + tableDef, + ...tableDef.isEvent ? { isEvent: true } : {} + }; +} +var ModuleContext = class { + #compoundTypes = /* @__PURE__ */ new Map(); + /** + * The global module definition that gets populated by calls to `reducer()` and lifecycle hooks. + */ + #moduleDef = { + typespace: { types: [] }, + tables: [], + reducers: [], + types: [], + rowLevelSecurity: [], + schedules: [], + procedures: [], + views: [], + lifeCycleReducers: [], + caseConversionPolicy: { tag: "SnakeCase" }, + explicitNames: { entries: [] } + }; + get moduleDef() { + return this.#moduleDef; + } + rawModuleDefV10() { + const sections = []; + const push = (s) => { + if (s) sections.push(s); + }; + const module = this.#moduleDef; + push(module.typespace && { + tag: "Typespace", + value: module.typespace + }); + push(module.types && { + tag: "Types", + value: module.types + }); + push(module.tables && { + tag: "Tables", + value: module.tables + }); + push(module.reducers && { + tag: "Reducers", + value: module.reducers + }); + push(module.procedures && { + tag: "Procedures", + value: module.procedures + }); + push(module.views && { + tag: "Views", + value: module.views + }); + push(module.schedules && { + tag: "Schedules", + value: module.schedules + }); + push(module.lifeCycleReducers && { + tag: "LifeCycleReducers", + value: module.lifeCycleReducers + }); + push(module.rowLevelSecurity && { + tag: "RowLevelSecurity", + value: module.rowLevelSecurity + }); + push(module.explicitNames && { + tag: "ExplicitNames", + value: module.explicitNames + }); + push(module.caseConversionPolicy && { + tag: "CaseConversionPolicy", + value: module.caseConversionPolicy + }); + return { sections }; + } + /** + * Set the case conversion policy for this module. + * Called by the settings mechanism. + */ + setCaseConversionPolicy(policy) { + this.#moduleDef.caseConversionPolicy = policy; + } + get typespace() { + return this.#moduleDef.typespace; + } + /** + * Resolves the actual type of a TypeBuilder by following its references until it reaches a non-ref type. + * @param typespace The typespace to resolve types against. + * @param typeBuilder The TypeBuilder to resolve. + * @returns The resolved algebraic type. + */ + resolveType(typeBuilder) { + let ty = typeBuilder.algebraicType; + while (ty.tag === "Ref") ty = this.typespace.types[ty.value]; + return ty; + } + /** + * Adds a type to the module definition's typespace as a `Ref` if it is a named compound type (Product or Sum). + * Otherwise, returns the type as is. + * @param name + * @param ty + * @returns + */ + registerTypesRecursively(typeBuilder) { + if (typeBuilder instanceof ProductBuilder && !isUnit(typeBuilder) || typeBuilder instanceof SumBuilder || typeBuilder instanceof RowBuilder) return this.#registerCompoundTypeRecursively(typeBuilder); + else if (typeBuilder instanceof OptionBuilder) return new OptionBuilder(this.registerTypesRecursively(typeBuilder.value)); + else if (typeBuilder instanceof ResultBuilder) return new ResultBuilder(this.registerTypesRecursively(typeBuilder.ok), this.registerTypesRecursively(typeBuilder.err)); + else if (typeBuilder instanceof ArrayBuilder) return new ArrayBuilder(this.registerTypesRecursively(typeBuilder.element)); + else return typeBuilder; + } + #registerCompoundTypeRecursively(typeBuilder) { + const ty = typeBuilder.algebraicType; + const name = typeBuilder.typeName; + if (name === void 0) throw new Error(`Missing type name for ${typeBuilder.constructor.name ?? "TypeBuilder"} ${JSON.stringify(typeBuilder)}`); + let r = this.#compoundTypes.get(ty); + if (r != null) return r; + const newTy = typeBuilder instanceof RowBuilder || typeBuilder instanceof ProductBuilder ? { + tag: "Product", + value: { elements: [] } + } : { + tag: "Sum", + value: { variants: [] } + }; + r = new RefBuilder(this.#moduleDef.typespace.types.length); + this.#moduleDef.typespace.types.push(newTy); + this.#compoundTypes.set(ty, r); + if (typeBuilder instanceof RowBuilder) for (const [name2, elem] of Object.entries(typeBuilder.row)) newTy.value.elements.push({ + name: name2, + algebraicType: this.registerTypesRecursively(elem.typeBuilder).algebraicType + }); + else if (typeBuilder instanceof ProductBuilder) for (const [name2, elem] of Object.entries(typeBuilder.elements)) newTy.value.elements.push({ + name: name2, + algebraicType: this.registerTypesRecursively(elem).algebraicType + }); + else if (typeBuilder instanceof SumBuilder) for (const [name2, variant] of Object.entries(typeBuilder.variants)) newTy.value.variants.push({ + name: name2, + algebraicType: this.registerTypesRecursively(variant).algebraicType + }); + this.#moduleDef.types.push({ + sourceName: splitName(name), + ty: r.ref, + customOrdering: true + }); + return r; + } +}; +function isUnit(typeBuilder) { + return typeBuilder.typeName == null && typeBuilder.algebraicType.value.elements.length === 0; +} +function splitName(name) { + const scope = name.split("."); + return { + sourceName: scope.pop(), + scope + }; +} +var import_statuses = __toESM(require_statuses()); +var Range = class { + #from; + #to; + constructor(from, to) { + this.#from = from ?? { tag: "unbounded" }; + this.#to = to ?? { tag: "unbounded" }; + } + get from() { + return this.#from; + } + get to() { + return this.#to; + } +}; +function table(opts, row, ..._) { + const { name, public: isPublic = false, indexes: userIndexes = [], scheduled, event: isEvent = false } = opts; + const colIds = /* @__PURE__ */ new Map(); + const colNameList = []; + if (!(row instanceof RowBuilder)) row = new RowBuilder(row); + row.algebraicType.value.elements.forEach((elem, i) => { + colIds.set(elem.name, i); + colNameList.push(elem.name); + }); + const pk = []; + const indexes = []; + const constraints = []; + const sequences = []; + let scheduleAtCol; + const defaultValues = []; + for (const [name2, builder] of Object.entries(row.row)) { + const meta = builder.columnMetadata; + if (meta.isPrimaryKey) pk.push(colIds.get(name2)); + const isUnique = meta.isUnique || meta.isPrimaryKey; + if (meta.indexType || isUnique) { + const algo = meta.indexType ?? "btree"; + const id = colIds.get(name2); + let algorithm; + switch (algo) { + case "btree": + algorithm = RawIndexAlgorithm.BTree([id]); + break; + case "hash": + algorithm = RawIndexAlgorithm.Hash([id]); + break; + case "direct": + algorithm = RawIndexAlgorithm.Direct(id); + break; + } + indexes.push({ + sourceName: void 0, + accessorName: name2, + algorithm + }); + } + if (isUnique) constraints.push({ + sourceName: void 0, + data: { + tag: "Unique", + value: { columns: [colIds.get(name2)] } + } + }); + if (meta.isAutoIncrement) sequences.push({ + sourceName: void 0, + start: void 0, + minValue: void 0, + maxValue: void 0, + column: colIds.get(name2), + increment: 1n + }); + if (meta.defaultValue) { + const writer = new BinaryWriter(16); + builder.serialize(writer, meta.defaultValue); + defaultValues.push({ + colId: colIds.get(name2), + value: writer.getBuffer() + }); + } + if (scheduled) { + const algebraicType = builder.typeBuilder.algebraicType; + if (schedule_at_default.isScheduleAt(algebraicType)) scheduleAtCol = colIds.get(name2); + } + } + for (const indexOpts of userIndexes ?? []) { + const accessor = indexOpts.accessor; + if (typeof accessor !== "string" || accessor.length === 0) { + const tableLabel = name ?? ""; + const indexLabel = indexOpts.name ?? ""; + throw new TypeError(`Index '${indexLabel}' on table '${tableLabel}' must define a non-empty 'accessor'`); + } + let algorithm; + switch (indexOpts.algorithm) { + case "btree": + algorithm = { + tag: "BTree", + value: indexOpts.columns.map((c) => colIds.get(c)) + }; + break; + case "hash": + algorithm = { + tag: "Hash", + value: indexOpts.columns.map((c) => colIds.get(c)) + }; + break; + case "direct": + algorithm = { + tag: "Direct", + value: colIds.get(indexOpts.column) + }; + break; + } + indexes.push({ + sourceName: void 0, + accessorName: accessor, + algorithm, + canonicalName: indexOpts.name + }); + } + for (const constraintOpts of opts.constraints ?? []) if (constraintOpts.constraint === "unique") { + const data = { + tag: "Unique", + value: { columns: constraintOpts.columns.map((c) => colIds.get(c)) } + }; + constraints.push({ + sourceName: constraintOpts.name, + data + }); + continue; + } + const productType = row.algebraicType.value; + return { + rowType: row, + tableName: name, + rowSpacetimeType: productType, + tableDef: (ctx, accName) => { + const tableName = name ?? accName; + if (row.typeName === void 0) row.typeName = toPascalCase(tableName); + for (const index of indexes) { + const sourceName = index.sourceName = `${accName}_${(index.algorithm.tag === "Direct" ? [index.algorithm.value] : index.algorithm.value).map((i) => colNameList[i]).join("_")}_idx_${index.algorithm.tag.toLowerCase()}`; + const { canonicalName } = index; + if (canonicalName !== void 0) ctx.moduleDef.explicitNames.entries.push(ExplicitNameEntry.Index({ + sourceName, + canonicalName + })); + } + return { + sourceName: accName, + productTypeRef: ctx.registerTypesRecursively(row).ref, + primaryKey: pk, + indexes, + constraints, + sequences, + tableType: { tag: "User" }, + tableAccess: { tag: isPublic ? "Public" : "Private" }, + defaultValues, + isEvent + }; + }, + idxs: userIndexes, + constraints, + schedule: scheduled && scheduleAtCol !== void 0 ? { + scheduleAtCol, + reducer: scheduled + } : void 0 + }; +} +var QueryBrand = Symbol("QueryBrand"); +var isRowTypedQuery = (val) => !!val && typeof val === "object" && QueryBrand in val; +function toSql(q) { + return q.toSql(); +} +var SemijoinImpl = class _SemijoinImpl { + constructor(sourceQuery, filterQuery, joinCondition) { + this.sourceQuery = sourceQuery; + this.filterQuery = filterQuery; + this.joinCondition = joinCondition; + if (sourceQuery.table.sourceName === filterQuery.table.sourceName) throw new Error("Cannot semijoin a table to itself"); + } + [QueryBrand] = true; + type = "semijoin"; + build() { + return this; + } + where(predicate) { + return new _SemijoinImpl(this.sourceQuery.where(predicate), this.filterQuery, this.joinCondition); + } + toSql() { + const left = this.filterQuery; + const right = this.sourceQuery; + const leftTable = quoteIdentifier(left.table.sourceName); + const rightTable = quoteIdentifier(right.table.sourceName); + let sql = `SELECT ${rightTable}.* FROM ${leftTable} JOIN ${rightTable} ON ${booleanExprToSql(this.joinCondition)}`; + const clauses = []; + if (left.whereClause) clauses.push(booleanExprToSql(left.whereClause)); + if (right.whereClause) clauses.push(booleanExprToSql(right.whereClause)); + if (clauses.length > 0) { + const whereSql = clauses.length === 1 ? clauses[0] : clauses.map(wrapInParens).join(" AND "); + sql += ` WHERE ${whereSql}`; + } + return sql; + } +}; +var FromBuilder = class _FromBuilder { + constructor(table2, whereClause) { + this.table = table2; + this.whereClause = whereClause; + } + [QueryBrand] = true; + where(predicate) { + const newCondition = normalizePredicateExpr(predicate(this.table.cols)); + const nextWhere = this.whereClause ? this.whereClause.and(newCondition) : newCondition; + return new _FromBuilder(this.table, nextWhere); + } + rightSemijoin(right, on) { + const sourceQuery = new _FromBuilder(right); + const joinCondition = on(this.table.indexedCols, right.indexedCols); + return new SemijoinImpl(sourceQuery, this, joinCondition); + } + leftSemijoin(right, on) { + const filterQuery = new _FromBuilder(right); + const joinCondition = on(this.table.indexedCols, right.indexedCols); + return new SemijoinImpl(this, filterQuery, joinCondition); + } + toSql() { + return renderSelectSqlWithJoins(this.table, this.whereClause); + } + build() { + return this; + } +}; +var TableRefImpl = class { + [QueryBrand] = true; + type = "table"; + sourceName; + accessorName; + cols; + indexedCols; + tableDef; + get columns() { + return this.tableDef.columns; + } + get indexes() { + return this.tableDef.indexes; + } + get rowType() { + return this.tableDef.rowType; + } + get constraints() { + return this.tableDef.constraints; + } + constructor(tableDef) { + this.sourceName = tableDef.sourceName; + this.accessorName = tableDef.accessorName; + this.cols = createRowExpr(tableDef); + this.indexedCols = this.cols; + this.tableDef = tableDef; + Object.freeze(this); + } + asFrom() { + return new FromBuilder(this); + } + rightSemijoin(other, on) { + return this.asFrom().rightSemijoin(other, on); + } + leftSemijoin(other, on) { + return this.asFrom().leftSemijoin(other, on); + } + build() { + return this.asFrom().build(); + } + toSql() { + return this.asFrom().toSql(); + } + where(predicate) { + return this.asFrom().where(predicate); + } +}; +function createTableRefFromDef(tableDef) { + return new TableRefImpl(tableDef); +} +function makeQueryBuilder(schema2) { + const qb = /* @__PURE__ */ Object.create(null); + for (const table2 of Object.values(schema2.tables)) { + const ref = createTableRefFromDef(table2); + qb[table2.accessorName] = ref; + } + return Object.freeze(qb); +} +function createRowExpr(tableDef) { + const row = {}; + for (const columnName of Object.keys(tableDef.columns)) { + const columnBuilder = tableDef.columns[columnName]; + const column = new ColumnExpression(tableDef.sourceName, columnName, columnBuilder.typeBuilder.algebraicType, columnBuilder.columnMetadata.name); + row[columnName] = Object.freeze(column); + } + return Object.freeze(row); +} +function renderSelectSqlWithJoins(table2, where, extraClauses = []) { + const sql = `SELECT * FROM ${quoteIdentifier(table2.sourceName)}`; + const clauses = []; + if (where) clauses.push(booleanExprToSql(where)); + clauses.push(...extraClauses); + if (clauses.length === 0) return sql; + return `${sql} WHERE ${clauses.length === 1 ? clauses[0] : clauses.map(wrapInParens).join(" AND ")}`; +} +var ColumnExpression = class { + type = "column"; + column; + columnName; + table; + tsValueType; + spacetimeType; + constructor(table2, column, spacetimeType, columnName) { + this.table = table2; + this.column = column; + this.columnName = columnName || column; + this.spacetimeType = spacetimeType; + } + eq(x) { + return new BooleanExpr({ + type: "eq", + left: this, + right: normalizeValue(x) + }); + } + ne(x) { + return new BooleanExpr({ + type: "ne", + left: this, + right: normalizeValue(x) + }); + } + lt(x) { + return new BooleanExpr({ + type: "lt", + left: this, + right: normalizeValue(x) + }); + } + lte(x) { + return new BooleanExpr({ + type: "lte", + left: this, + right: normalizeValue(x) + }); + } + gt(x) { + return new BooleanExpr({ + type: "gt", + left: this, + right: normalizeValue(x) + }); + } + gte(x) { + return new BooleanExpr({ + type: "gte", + left: this, + right: normalizeValue(x) + }); + } +}; +function literal(value) { + return { + type: "literal", + value + }; +} +function normalizeValue(val) { + if (val.type === "literal") return val; + if (typeof val === "object" && val != null && "type" in val && val.type === "column") return val; + return literal(val); +} +function normalizePredicateExpr(value) { + if (value instanceof BooleanExpr) return value; + if (typeof value === "boolean") return new BooleanExpr({ + type: "eq", + left: literal(value), + right: literal(true) + }); + return new BooleanExpr({ + type: "eq", + left: value, + right: literal(true) + }); +} +var BooleanExpr = class _BooleanExpr { + constructor(data) { + this.data = data; + } + and(other) { + return new _BooleanExpr({ + type: "and", + clauses: [this.data, other.data] + }); + } + or(other) { + return new _BooleanExpr({ + type: "or", + clauses: [this.data, other.data] + }); + } + not() { + return new _BooleanExpr({ + type: "not", + clause: this.data + }); + } +}; +function booleanExprToSql(expr, tableAlias) { + const data = expr instanceof BooleanExpr ? expr.data : expr; + switch (data.type) { + case "eq": return `${valueExprToSql(data.left)} = ${valueExprToSql(data.right)}`; + case "ne": return `${valueExprToSql(data.left)} <> ${valueExprToSql(data.right)}`; + case "gt": return `${valueExprToSql(data.left)} > ${valueExprToSql(data.right)}`; + case "gte": return `${valueExprToSql(data.left)} >= ${valueExprToSql(data.right)}`; + case "lt": return `${valueExprToSql(data.left)} < ${valueExprToSql(data.right)}`; + case "lte": return `${valueExprToSql(data.left)} <= ${valueExprToSql(data.right)}`; + case "and": return data.clauses.map((c) => booleanExprToSql(c)).map(wrapInParens).join(" AND "); + case "or": return data.clauses.map((c) => booleanExprToSql(c)).map(wrapInParens).join(" OR "); + case "not": return `NOT ${wrapInParens(booleanExprToSql(data.clause))}`; + } +} +function wrapInParens(sql) { + return `(${sql})`; +} +function valueExprToSql(expr, tableAlias) { + if (isLiteralExpr(expr)) return literalValueToSql(expr.value); + const table2 = expr.table; + return `${quoteIdentifier(table2)}.${quoteIdentifier(expr.columnName)}`; +} +function literalValueToSql(value) { + if (value === null || value === void 0) return "NULL"; + if (value instanceof Identity || value instanceof ConnectionId) return `0x${value.toHexString()}`; + if (value instanceof Timestamp) return `'${value.toISOString()}'`; + switch (typeof value) { + case "number": + case "bigint": return String(value); + case "boolean": return value ? "TRUE" : "FALSE"; + case "string": return `'${value.replace(/'/g, "''")}'`; + default: return `'${JSON.stringify(value).replace(/'/g, "''")}'`; + } +} +function quoteIdentifier(name) { + return `"${name.replace(/"/g, "\"\"")}"`; +} +function isLiteralExpr(expr) { + return expr.type === "literal"; +} +function makeViewExport(ctx, opts, params, ret, fn) { + const viewExport = fn.bind(); + viewExport[exportContext] = ctx; + viewExport[registerExport] = (ctx2, exportName) => { + registerView(ctx2, opts, exportName, false, params, ret, fn); + }; + return viewExport; +} +function makeAnonViewExport(ctx, opts, params, ret, fn) { + const viewExport = fn.bind(); + viewExport[exportContext] = ctx; + viewExport[registerExport] = (ctx2, exportName) => { + registerView(ctx2, opts, exportName, true, params, ret, fn); + }; + return viewExport; +} +function registerView(ctx, opts, exportName, anon, params, ret, fn) { + const paramsBuilder = new RowBuilder(params, toPascalCase(exportName)); + let returnType = ctx.registerTypesRecursively(ret).algebraicType; + const { typespace } = ctx; + const { value: paramType } = ctx.resolveType(ctx.registerTypesRecursively(paramsBuilder)); + ctx.moduleDef.views.push({ + sourceName: exportName, + index: (anon ? ctx.anonViews : ctx.views).length, + isPublic: opts.public, + isAnonymous: anon, + params: paramType, + returnType + }); + if (opts.name != null) ctx.moduleDef.explicitNames.entries.push({ + tag: "Function", + value: { + sourceName: exportName, + canonicalName: opts.name + } + }); + if (returnType.tag == "Sum") { + const originalFn = fn; + fn = ((ctx2, args) => { + const ret2 = originalFn(ctx2, args); + return ret2 == null ? [] : [ret2]; + }); + returnType = AlgebraicType.Array(returnType.value.variants[0].algebraicType); + } + (anon ? ctx.anonViews : ctx.views).push({ + fn, + deserializeParams: ProductType.makeDeserializer(paramType, typespace), + serializeReturn: AlgebraicType.makeSerializer(returnType, typespace), + returnTypeBaseSize: bsatnBaseSize(typespace, returnType) + }); +} +var SenderError = class extends Error { + constructor(message) { + super(message); + } + get name() { + return "SenderError"; + } +}; +var SpacetimeHostError = class extends Error { + constructor(message) { + super(message); + } + get name() { + return "SpacetimeHostError"; + } +}; +var errorData = { + HostCallFailure: 1, + NotInTransaction: 2, + BsatnDecodeError: 3, + NoSuchTable: 4, + NoSuchIndex: 5, + NoSuchIter: 6, + NoSuchConsoleTimer: 7, + NoSuchBytes: 8, + NoSpace: 9, + BufferTooSmall: 11, + UniqueAlreadyExists: 12, + ScheduleAtDelayTooLong: 13, + IndexNotUnique: 14, + NoSuchRow: 15, + AutoIncOverflow: 16, + WouldBlockTransaction: 17, + TransactionNotAnonymous: 18, + TransactionIsReadOnly: 19, + TransactionIsMut: 20, + HttpError: 21 +}; +function mapEntries(x, f) { + return Object.fromEntries(Object.entries(x).map(([k, v]) => [k, f(k, v)])); +} +var errnoToClass = /* @__PURE__ */ new Map(); +var errors = Object.freeze(mapEntries(errorData, (name, code) => { + const cls = Object.defineProperty(class extends SpacetimeHostError { + get name() { + return name; + } + }, "name", { + value: name, + writable: false + }); + errnoToClass.set(code, cls); + return cls; +})); +function getErrorConstructor(code) { + return errnoToClass.get(code) ?? SpacetimeHostError; +} +var SBigInt = typeof BigInt !== "undefined" ? BigInt : void 0; +var One = typeof BigInt !== "undefined" ? BigInt(1) : void 0; +var ThirtyTwo = typeof BigInt !== "undefined" ? BigInt(32) : void 0; +var NumValues = typeof BigInt !== "undefined" ? BigInt(4294967296) : void 0; +function unsafeUniformBigIntDistribution(from, to, rng) { + var diff = to - from + One; + var FinalNumValues = NumValues; + var NumIterations = 1; + while (FinalNumValues < diff) { + FinalNumValues <<= ThirtyTwo; + ++NumIterations; + } + var value = generateNext(NumIterations, rng); + if (value < diff) return value + from; + if (value + diff < FinalNumValues) return value % diff + from; + var MaxAcceptedRandom = FinalNumValues - FinalNumValues % diff; + while (value >= MaxAcceptedRandom) value = generateNext(NumIterations, rng); + return value % diff + from; +} +function generateNext(NumIterations, rng) { + var value = SBigInt(rng.unsafeNext() + 2147483648); + for (var num = 1; num < NumIterations; ++num) { + var out = rng.unsafeNext(); + value = (value << ThirtyTwo) + SBigInt(out + 2147483648); + } + return value; +} +function unsafeUniformIntDistributionInternal(rangeSize, rng) { + var MaxAllowed = rangeSize > 2 ? ~~(4294967296 / rangeSize) * rangeSize : 4294967296; + var deltaV = rng.unsafeNext() + 2147483648; + while (deltaV >= MaxAllowed) deltaV = rng.unsafeNext() + 2147483648; + return deltaV % rangeSize; +} +function fromNumberToArrayInt64(out, n) { + if (n < 0) { + var posN = -n; + out.sign = -1; + out.data[0] = ~~(posN / 4294967296); + out.data[1] = posN >>> 0; + } else { + out.sign = 1; + out.data[0] = ~~(n / 4294967296); + out.data[1] = n >>> 0; + } + return out; +} +function substractArrayInt64(out, arrayIntA, arrayIntB) { + var lowA = arrayIntA.data[1]; + var highA = arrayIntA.data[0]; + var signA = arrayIntA.sign; + var lowB = arrayIntB.data[1]; + var highB = arrayIntB.data[0]; + var signB = arrayIntB.sign; + out.sign = 1; + if (signA === 1 && signB === -1) { + var low_1 = lowA + lowB; + var high = highA + highB + (low_1 > 4294967295 ? 1 : 0); + out.data[0] = high >>> 0; + out.data[1] = low_1 >>> 0; + return out; + } + var lowFirst = lowA; + var highFirst = highA; + var lowSecond = lowB; + var highSecond = highB; + if (signA === -1) { + lowFirst = lowB; + highFirst = highB; + lowSecond = lowA; + highSecond = highA; + } + var reminderLow = 0; + var low = lowFirst - lowSecond; + if (low < 0) { + reminderLow = 1; + low = low >>> 0; + } + out.data[0] = highFirst - highSecond - reminderLow; + out.data[1] = low; + return out; +} +function unsafeUniformArrayIntDistributionInternal(out, rangeSize, rng) { + var rangeLength = rangeSize.length; + while (true) { + for (var index = 0; index !== rangeLength; ++index) out[index] = unsafeUniformIntDistributionInternal(index === 0 ? rangeSize[0] + 1 : 4294967296, rng); + for (var index = 0; index !== rangeLength; ++index) { + var current = out[index]; + var currentInRange = rangeSize[index]; + if (current < currentInRange) return out; + else if (current > currentInRange) break; + } + } +} +var safeNumberMaxSafeInteger = Number.MAX_SAFE_INTEGER; +var sharedA = { + sign: 1, + data: [0, 0] +}; +var sharedB = { + sign: 1, + data: [0, 0] +}; +var sharedC = { + sign: 1, + data: [0, 0] +}; +var sharedData = [0, 0]; +function uniformLargeIntInternal(from, to, rangeSize, rng) { + var rangeSizeArrayIntValue = rangeSize <= safeNumberMaxSafeInteger ? fromNumberToArrayInt64(sharedC, rangeSize) : substractArrayInt64(sharedC, fromNumberToArrayInt64(sharedA, to), fromNumberToArrayInt64(sharedB, from)); + if (rangeSizeArrayIntValue.data[1] === 4294967295) { + rangeSizeArrayIntValue.data[0] += 1; + rangeSizeArrayIntValue.data[1] = 0; + } else rangeSizeArrayIntValue.data[1] += 1; + unsafeUniformArrayIntDistributionInternal(sharedData, rangeSizeArrayIntValue.data, rng); + return sharedData[0] * 4294967296 + sharedData[1] + from; +} +function unsafeUniformIntDistribution(from, to, rng) { + var rangeSize = to - from; + if (rangeSize <= 4294967295) return unsafeUniformIntDistributionInternal(rangeSize + 1, rng) + from; + return uniformLargeIntInternal(from, to, rangeSize, rng); +} +var XoroShiro128Plus = (function() { + function XoroShiro128Plus2(s01, s00, s11, s10) { + this.s01 = s01; + this.s00 = s00; + this.s11 = s11; + this.s10 = s10; + } + XoroShiro128Plus2.prototype.clone = function() { + return new XoroShiro128Plus2(this.s01, this.s00, this.s11, this.s10); + }; + XoroShiro128Plus2.prototype.next = function() { + var nextRng = new XoroShiro128Plus2(this.s01, this.s00, this.s11, this.s10); + return [nextRng.unsafeNext(), nextRng]; + }; + XoroShiro128Plus2.prototype.unsafeNext = function() { + var out = this.s00 + this.s10 | 0; + var a0 = this.s10 ^ this.s00; + var a1 = this.s11 ^ this.s01; + var s00 = this.s00; + var s01 = this.s01; + this.s00 = s00 << 24 ^ s01 >>> 8 ^ a0 ^ a0 << 16; + this.s01 = s01 << 24 ^ s00 >>> 8 ^ a1 ^ (a1 << 16 | a0 >>> 16); + this.s10 = a1 << 5 ^ a0 >>> 27; + this.s11 = a0 << 5 ^ a1 >>> 27; + return out; + }; + XoroShiro128Plus2.prototype.jump = function() { + var nextRng = new XoroShiro128Plus2(this.s01, this.s00, this.s11, this.s10); + nextRng.unsafeJump(); + return nextRng; + }; + XoroShiro128Plus2.prototype.unsafeJump = function() { + var ns01 = 0; + var ns00 = 0; + var ns11 = 0; + var ns10 = 0; + var jump = [ + 3639956645, + 3750757012, + 1261568508, + 386426335 + ]; + for (var i = 0; i !== 4; ++i) for (var mask = 1; mask; mask <<= 1) { + if (jump[i] & mask) { + ns01 ^= this.s01; + ns00 ^= this.s00; + ns11 ^= this.s11; + ns10 ^= this.s10; + } + this.unsafeNext(); + } + this.s01 = ns01; + this.s00 = ns00; + this.s11 = ns11; + this.s10 = ns10; + }; + XoroShiro128Plus2.prototype.getState = function() { + return [ + this.s01, + this.s00, + this.s11, + this.s10 + ]; + }; + return XoroShiro128Plus2; +})(); +function fromState(state) { + if (!(state.length === 4)) throw new Error("The state must have been produced by a xoroshiro128plus RandomGenerator"); + return new XoroShiro128Plus(state[0], state[1], state[2], state[3]); +} +var xoroshiro128plus = Object.assign(function(seed) { + return new XoroShiro128Plus(-1, ~seed, seed | 0, 0); +}, { fromState }); +var { asUintN } = BigInt; +function pcg32(state) { + state = asUintN(64, state * 6364136223846793005n + 11634580027462260723n); + const xorshifted = Number(asUintN(32, (state >> 18n ^ state) >> 27n)); + const rot = Number(asUintN(32, state >> 59n)); + return xorshifted >> rot | xorshifted << 32 - rot; +} +function generateFloat64(rng) { + const g1 = unsafeUniformIntDistribution(0, (1 << 26) - 1, rng); + const g2 = unsafeUniformIntDistribution(0, (1 << 27) - 1, rng); + return (g1 * Math.pow(2, 27) + g2) * Math.pow(2, -53); +} +function makeRandom(seed) { + const rng = xoroshiro128plus(pcg32(seed.microsSinceUnixEpoch)); + const random = () => generateFloat64(rng); + random.fill = (array) => { + const elem = array.at(0); + if (typeof elem === "bigint") { + const upper = (1n << BigInt(array.BYTES_PER_ELEMENT * 8)) - 1n; + for (let i = 0; i < array.length; i++) array[i] = unsafeUniformBigIntDistribution(0n, upper, rng); + } else if (typeof elem === "number") { + const upper = (1 << array.BYTES_PER_ELEMENT * 8) - 1; + for (let i = 0; i < array.length; i++) array[i] = unsafeUniformIntDistribution(0, upper, rng); + } + return array; + }; + random.uint32 = () => rng.unsafeNext(); + random.integerInRange = (min, max) => unsafeUniformIntDistribution(min, max, rng); + random.bigintInRange = (min, max) => unsafeUniformBigIntDistribution(min, max, rng); + return random; +} +var { freeze } = Object; +var sys = _syscalls2_0; +function parseJsonObject(json) { + let value; + try { + value = JSON.parse(json); + } catch { + throw new Error("Invalid JSON: failed to parse string"); + } + if (value === null || typeof value !== "object" || Array.isArray(value)) throw new Error("Expected a JSON object at the top level"); + return value; +} +var JwtClaimsImpl = class { + /** + * Creates a new JwtClaims instance. + * @param rawPayload The JWT payload as a raw JSON string. + * @param identity The identity for this JWT. We are only taking this because we don't have a blake3 implementation (which we need to compute it). + */ + constructor(rawPayload, identity) { + this.rawPayload = rawPayload; + this.fullPayload = parseJsonObject(rawPayload); + this._identity = identity; + } + fullPayload; + _identity; + get identity() { + return this._identity; + } + get subject() { + return this.fullPayload["sub"]; + } + get issuer() { + return this.fullPayload["iss"]; + } + get audience() { + const aud = this.fullPayload["aud"]; + if (aud == null) return []; + return typeof aud === "string" ? [aud] : aud; + } +}; +var AuthCtxImpl = class _AuthCtxImpl { + isInternal; + _jwtSource; + _initializedJWT = false; + _jwtClaims; + _senderIdentity; + constructor(opts) { + this.isInternal = opts.isInternal; + this._jwtSource = opts.jwtSource; + this._senderIdentity = opts.senderIdentity; + } + _initializeJWT() { + if (this._initializedJWT) return; + this._initializedJWT = true; + const token = this._jwtSource(); + if (!token) this._jwtClaims = null; + else this._jwtClaims = new JwtClaimsImpl(token, this._senderIdentity); + Object.freeze(this); + } + /** Lazily compute whether a JWT exists and is parseable. */ + get hasJWT() { + this._initializeJWT(); + return this._jwtClaims !== null; + } + /** Lazily parse the JwtClaims only when accessed. */ + get jwt() { + this._initializeJWT(); + return this._jwtClaims; + } + /** Create a context representing internal (non-user) requests. */ + static internal() { + return new _AuthCtxImpl({ + isInternal: true, + jwtSource: () => null, + senderIdentity: Identity.zero() + }); + } + /** If there is a connection id, look up the JWT payload from the system tables. */ + static fromSystemTables(connectionId, sender) { + if (connectionId === null) return new _AuthCtxImpl({ + isInternal: false, + jwtSource: () => null, + senderIdentity: sender + }); + return new _AuthCtxImpl({ + isInternal: false, + jwtSource: () => { + const payloadBuf = sys.get_jwt_payload(connectionId.__connection_id__); + if (payloadBuf.length === 0) return null; + return new TextDecoder().decode(payloadBuf); + }, + senderIdentity: sender + }); + } +}; +var ReducerCtxImpl = class ReducerCtx { + #identity; + #senderAuth; + #uuidCounter; + #random; + sender; + timestamp; + connectionId; + db; + constructor(sender, timestamp, connectionId, dbView) { + Object.seal(this); + this.sender = sender; + this.timestamp = timestamp; + this.connectionId = connectionId; + this.db = dbView; + } + /** Reset the `ReducerCtx` to be used for a new transaction */ + static reset(me, sender, timestamp, connectionId) { + me.sender = sender; + me.timestamp = timestamp; + me.connectionId = connectionId; + me.#uuidCounter = void 0; + me.#senderAuth = void 0; + } + get identity() { + return this.#identity ??= new Identity(sys.identity()); + } + get senderAuth() { + return this.#senderAuth ??= AuthCtxImpl.fromSystemTables(this.connectionId, this.sender); + } + get random() { + return this.#random ??= makeRandom(this.timestamp); + } + /** + * Create a new random {@link Uuid} `v4` using this `ReducerCtx`'s RNG. + */ + newUuidV4() { + const bytes = this.random.fill(new Uint8Array(16)); + return Uuid.fromRandomBytesV4(bytes); + } + /** + * Create a new sortable {@link Uuid} `v7` using this `ReducerCtx`'s RNG, counter, + * and timestamp. + */ + newUuidV7() { + const bytes = this.random.fill(new Uint8Array(4)); + const counter = this.#uuidCounter ??= { value: 0 }; + return Uuid.fromCounterV7(counter, this.timestamp, bytes); + } +}; +var callUserFunction = function __spacetimedb_end_short_backtrace(fn, ...args) { + return fn(...args); +}; +var makeHooks = (schema2) => new ModuleHooksImpl(schema2); +var ModuleHooksImpl = class { + #schema; + #dbView_; + #reducerArgsDeserializers; + /** Cache the `ReducerCtx` object to avoid allocating anew for ever reducer call. */ + #reducerCtx_; + constructor(schema2) { + this.#schema = schema2; + this.#reducerArgsDeserializers = schema2.moduleDef.reducers.map(({ params }) => ProductType.makeDeserializer(params, schema2.typespace)); + } + get #dbView() { + return this.#dbView_ ??= freeze(Object.fromEntries(Object.values(this.#schema.schemaType.tables).map((table2) => [table2.accessorName, makeTableView(this.#schema.typespace, table2.tableDef)]))); + } + get #reducerCtx() { + return this.#reducerCtx_ ??= new ReducerCtxImpl(Identity.zero(), Timestamp.UNIX_EPOCH, null, this.#dbView); + } + __describe_module__() { + const writer = new BinaryWriter(128); + RawModuleDef.serialize(writer, RawModuleDef.V10(this.#schema.rawModuleDefV10())); + return writer.getBuffer(); + } + __get_error_constructor__(code) { + return getErrorConstructor(code); + } + get __sender_error_class__() { + return SenderError; + } + __call_reducer__(reducerId, sender, connId, timestamp, argsBuf) { + const moduleCtx = this.#schema; + const deserializeArgs = this.#reducerArgsDeserializers[reducerId]; + BINARY_READER.reset(argsBuf); + const args = deserializeArgs(BINARY_READER); + const senderIdentity = new Identity(sender); + const ctx = this.#reducerCtx; + ReducerCtxImpl.reset(ctx, senderIdentity, new Timestamp(timestamp), ConnectionId.nullIfZero(new ConnectionId(connId))); + callUserFunction(moduleCtx.reducers[reducerId], ctx, args); + } + __call_view__(id, sender, argsBuf) { + const moduleCtx = this.#schema; + const { fn, deserializeParams, serializeReturn, returnTypeBaseSize } = moduleCtx.views[id]; + const ret = callUserFunction(fn, freeze({ + sender: new Identity(sender), + db: this.#dbView, + from: makeQueryBuilder(moduleCtx.schemaType) + }), deserializeParams(new BinaryReader(argsBuf))); + const retBuf = new BinaryWriter(returnTypeBaseSize); + if (isRowTypedQuery(ret)) { + const query = toSql(ret); + ViewResultHeader.serialize(retBuf, ViewResultHeader.RawSql(query)); + } else { + ViewResultHeader.serialize(retBuf, ViewResultHeader.RowData); + serializeReturn(retBuf, ret); + } + return { data: retBuf.getBuffer() }; + } + __call_view_anon__(id, argsBuf) { + const moduleCtx = this.#schema; + const { fn, deserializeParams, serializeReturn, returnTypeBaseSize } = moduleCtx.anonViews[id]; + const ret = callUserFunction(fn, freeze({ + db: this.#dbView, + from: makeQueryBuilder(moduleCtx.schemaType) + }), deserializeParams(new BinaryReader(argsBuf))); + const retBuf = new BinaryWriter(returnTypeBaseSize); + if (isRowTypedQuery(ret)) { + const query = toSql(ret); + ViewResultHeader.serialize(retBuf, ViewResultHeader.RawSql(query)); + } else { + ViewResultHeader.serialize(retBuf, ViewResultHeader.RowData); + serializeReturn(retBuf, ret); + } + return { data: retBuf.getBuffer() }; + } + __call_procedure__(id, sender, connection_id, timestamp, args) { + return callProcedure(this.#schema, id, new Identity(sender), ConnectionId.nullIfZero(new ConnectionId(connection_id)), new Timestamp(timestamp), args, () => this.#dbView); + } +}; +var BINARY_WRITER = new BinaryWriter(0); +var BINARY_READER = new BinaryReader(new Uint8Array()); +function makeTableView(typespace, table2) { + const table_id = sys.table_id_from_name(table2.sourceName); + const rowType = typespace.types[table2.productTypeRef]; + if (rowType.tag !== "Product") throw "impossible"; + const serializeRow = AlgebraicType.makeSerializer(rowType, typespace); + const deserializeRow = AlgebraicType.makeDeserializer(rowType, typespace); + const sequences = table2.sequences.map((seq) => { + const col = rowType.value.elements[seq.column]; + const colType = col.algebraicType; + let sequenceTrigger; + switch (colType.tag) { + case "U8": + case "I8": + case "U16": + case "I16": + case "U32": + case "I32": + sequenceTrigger = 0; + break; + case "U64": + case "I64": + case "U128": + case "I128": + case "U256": + case "I256": + sequenceTrigger = 0n; + break; + default: throw new TypeError("invalid sequence type"); + } + return { + colName: col.name, + sequenceTrigger, + deserialize: AlgebraicType.makeDeserializer(colType, typespace) + }; + }); + const hasAutoIncrement = sequences.length > 0; + const iter = () => tableIterator(sys.datastore_table_scan_bsatn(table_id), deserializeRow); + const integrateGeneratedColumns = hasAutoIncrement ? (row, ret_buf) => { + BINARY_READER.reset(ret_buf); + for (const { colName, deserialize, sequenceTrigger } of sequences) if (row[colName] === sequenceTrigger) row[colName] = deserialize(BINARY_READER); + } : null; + const tableMethods = { + count: () => sys.datastore_table_row_count(table_id), + iter, + [Symbol.iterator]: () => iter(), + insert: (row) => { + const buf = LEAF_BUF; + BINARY_WRITER.reset(buf); + serializeRow(BINARY_WRITER, row); + sys.datastore_insert_bsatn(table_id, buf.buffer, BINARY_WRITER.offset); + const ret = { ...row }; + integrateGeneratedColumns?.(ret, buf.view); + return ret; + }, + delete: (row) => { + const buf = LEAF_BUF; + BINARY_WRITER.reset(buf); + BINARY_WRITER.writeU32(1); + serializeRow(BINARY_WRITER, row); + return sys.datastore_delete_all_by_eq_bsatn(table_id, buf.buffer, BINARY_WRITER.offset) > 0; + } + }; + const tableView = Object.assign(/* @__PURE__ */ Object.create(null), tableMethods); + for (const indexDef of table2.indexes) { + const accessorName = indexDef.accessorName; + const index_id = sys.index_id_from_name(indexDef.sourceName); + let column_ids; + let isHashIndex = false; + switch (indexDef.algorithm.tag) { + case "Hash": + isHashIndex = true; + column_ids = indexDef.algorithm.value; + break; + case "BTree": + column_ids = indexDef.algorithm.value; + break; + case "Direct": + column_ids = [indexDef.algorithm.value]; + break; + } + const numColumns = column_ids.length; + const columnSet = new Set(column_ids); + const isUnique = table2.constraints.filter((x) => x.data.tag === "Unique").some((x) => columnSet.isSubsetOf(new Set(x.data.value.columns))); + const isPrimaryKey = isUnique && column_ids.length === table2.primaryKey.length && column_ids.every((id, i) => table2.primaryKey[i] === id); + const indexSerializers = column_ids.map((id) => AlgebraicType.makeSerializer(rowType.value.elements[id].algebraicType, typespace)); + const serializePoint = (buffer, colVal) => { + BINARY_WRITER.reset(buffer); + for (let i = 0; i < numColumns; i++) indexSerializers[i](BINARY_WRITER, colVal[i]); + return BINARY_WRITER.offset; + }; + const serializeSingleElement = numColumns === 1 ? indexSerializers[0] : null; + const serializeSinglePoint = serializeSingleElement && ((buffer, colVal) => { + BINARY_WRITER.reset(buffer); + serializeSingleElement(BINARY_WRITER, colVal); + return BINARY_WRITER.offset; + }); + let index; + if (isUnique && serializeSinglePoint) { + const base = { + find: (colVal) => { + const buf = LEAF_BUF; + const point_len = serializeSinglePoint(buf, colVal); + return tableIterateOne(sys.datastore_index_scan_point_bsatn(index_id, buf.buffer, point_len), deserializeRow); + }, + delete: (colVal) => { + const buf = LEAF_BUF; + const point_len = serializeSinglePoint(buf, colVal); + return sys.datastore_delete_by_index_scan_point_bsatn(index_id, buf.buffer, point_len) > 0; + } + }; + if (isPrimaryKey) base.update = (row) => { + const buf = LEAF_BUF; + BINARY_WRITER.reset(buf); + serializeRow(BINARY_WRITER, row); + sys.datastore_update_bsatn(table_id, index_id, buf.buffer, BINARY_WRITER.offset); + integrateGeneratedColumns?.(row, buf.view); + return row; + }; + index = base; + } else if (isUnique) { + const base = { + find: (colVal) => { + if (colVal.length !== numColumns) throw new TypeError("wrong number of elements"); + const buf = LEAF_BUF; + const point_len = serializePoint(buf, colVal); + return tableIterateOne(sys.datastore_index_scan_point_bsatn(index_id, buf.buffer, point_len), deserializeRow); + }, + delete: (colVal) => { + if (colVal.length !== numColumns) throw new TypeError("wrong number of elements"); + const buf = LEAF_BUF; + const point_len = serializePoint(buf, colVal); + return sys.datastore_delete_by_index_scan_point_bsatn(index_id, buf.buffer, point_len) > 0; + } + }; + if (isPrimaryKey) base.update = (row) => { + const buf = LEAF_BUF; + BINARY_WRITER.reset(buf); + serializeRow(BINARY_WRITER, row); + sys.datastore_update_bsatn(table_id, index_id, buf.buffer, BINARY_WRITER.offset); + integrateGeneratedColumns?.(row, buf.view); + return row; + }; + index = base; + } else if (serializeSinglePoint) { + const rawIndex = { + filter: (range) => { + const buf = LEAF_BUF; + const point_len = serializeSinglePoint(buf, range); + return tableIterator(sys.datastore_index_scan_point_bsatn(index_id, buf.buffer, point_len), deserializeRow); + }, + delete: (range) => { + const buf = LEAF_BUF; + const point_len = serializeSinglePoint(buf, range); + return sys.datastore_delete_by_index_scan_point_bsatn(index_id, buf.buffer, point_len); + } + }; + if (isHashIndex) index = rawIndex; + else index = rawIndex; + } else if (isHashIndex) index = { + filter: (range) => { + const buf = LEAF_BUF; + const point_len = serializePoint(buf, range); + return tableIterator(sys.datastore_index_scan_point_bsatn(index_id, buf.buffer, point_len), deserializeRow); + }, + delete: (range) => { + const buf = LEAF_BUF; + const point_len = serializePoint(buf, range); + return sys.datastore_delete_by_index_scan_point_bsatn(index_id, buf.buffer, point_len); + } + }; + else { + const serializeRange = (buffer, range) => { + if (range.length > numColumns) throw new TypeError("too many elements"); + BINARY_WRITER.reset(buffer); + const writer = BINARY_WRITER; + const prefix_elems = range.length - 1; + for (let i = 0; i < prefix_elems; i++) indexSerializers[i](writer, range[i]); + const rstartOffset = writer.offset; + const term = range[range.length - 1]; + const serializeTerm = indexSerializers[range.length - 1]; + if (term instanceof Range) { + const writeBound = (bound) => { + writer.writeU8({ + included: 0, + excluded: 1, + unbounded: 2 + }[bound.tag]); + if (bound.tag !== "unbounded") serializeTerm(writer, bound.value); + }; + writeBound(term.from); + const rstartLen = writer.offset - rstartOffset; + writeBound(term.to); + return [ + rstartOffset, + prefix_elems, + rstartLen, + writer.offset - rstartLen + ]; + } else { + writer.writeU8(0); + serializeTerm(writer, term); + return [ + rstartOffset, + prefix_elems, + writer.offset, + 0 + ]; + } + }; + index = { + filter: (range) => { + if (range.length === numColumns) { + const buf = LEAF_BUF; + const point_len = serializePoint(buf, range); + return tableIterator(sys.datastore_index_scan_point_bsatn(index_id, buf.buffer, point_len), deserializeRow); + } else { + const buf = LEAF_BUF; + const args = serializeRange(buf, range); + return tableIterator(sys.datastore_index_scan_range_bsatn(index_id, buf.buffer, ...args), deserializeRow); + } + }, + delete: (range) => { + if (range.length === numColumns) { + const buf = LEAF_BUF; + const point_len = serializePoint(buf, range); + return sys.datastore_delete_by_index_scan_point_bsatn(index_id, buf.buffer, point_len); + } else { + const buf = LEAF_BUF; + const args = serializeRange(buf, range); + return sys.datastore_delete_by_index_scan_range_bsatn(index_id, buf.buffer, ...args); + } + } + }; + } + if (Object.hasOwn(tableView, accessorName)) freeze(Object.assign(tableView[accessorName], index)); + else tableView[accessorName] = freeze(index); + } + return freeze(tableView); +} +function* tableIterator(id, deserialize) { + using iter = new IteratorHandle(id); + const iterBuf = takeBuf(); + try { + let amt; + while (amt = iter.advance(iterBuf)) { + const reader = new BinaryReader(iterBuf.view); + while (reader.offset < amt) yield deserialize(reader); + } + } finally { + returnBuf(iterBuf); + } +} +function tableIterateOne(id, deserialize) { + const buf = LEAF_BUF; + if (advanceIterRaw(id, buf) !== 0) { + BINARY_READER.reset(buf.view); + return deserialize(BINARY_READER); + } + return null; +} +function advanceIterRaw(id, buf) { + while (true) try { + return 0 | sys.row_iter_bsatn_advance(id, buf.buffer); + } catch (e) { + if (e && typeof e === "object" && hasOwn(e, "__buffer_too_small__")) { + buf.grow(e.__buffer_too_small__); + continue; + } + throw e; + } +} +var DEFAULT_BUFFER_CAPACITY = 32 * 1024 * 2; +var ITER_BUFS = [new ResizableBuffer(DEFAULT_BUFFER_CAPACITY)]; +var ITER_BUF_COUNT = 1; +function takeBuf() { + return ITER_BUF_COUNT ? ITER_BUFS[--ITER_BUF_COUNT] : new ResizableBuffer(DEFAULT_BUFFER_CAPACITY); +} +function returnBuf(buf) { + ITER_BUFS[ITER_BUF_COUNT++] = buf; +} +var LEAF_BUF = new ResizableBuffer(DEFAULT_BUFFER_CAPACITY); +var IteratorHandle = class _IteratorHandle { + #id; + static #finalizationRegistry = new FinalizationRegistry(sys.row_iter_bsatn_close); + constructor(id) { + this.#id = id; + _IteratorHandle.#finalizationRegistry.register(this, id, this); + } + /** Unregister this object with the finalization registry and return the id */ + #detach() { + const id = this.#id; + this.#id = -1; + _IteratorHandle.#finalizationRegistry.unregister(this); + return id; + } + /** Call `row_iter_bsatn_advance`, returning 0 if this iterator has been exhausted. */ + advance(buf) { + if (this.#id === -1) return 0; + const ret = advanceIterRaw(this.#id, buf); + if (ret <= 0) this.#detach(); + return ret < 0 ? -ret : ret; + } + [Symbol.dispose]() { + if (this.#id >= 0) { + const id = this.#detach(); + sys.row_iter_bsatn_close(id); + } + } +}; +var { freeze: freeze2 } = Object; +var textEncoder = new TextEncoder(); +var textDecoder = new TextDecoder("utf-8"); +var makeResponse = Symbol("makeResponse"); +var SyncResponse = class _SyncResponse { + #body; + #inner; + constructor(body, init) { + if (body == null) this.#body = null; + else if (typeof body === "string") this.#body = body; + else this.#body = new Uint8Array(body).buffer; + this.#inner = { + headers: new Headers(init?.headers), + status: init?.status ?? 200, + statusText: init?.statusText ?? "", + type: "default", + url: null, + aborted: false + }; + } + static [makeResponse](body, inner) { + const me = new _SyncResponse(body); + me.#inner = inner; + return me; + } + get headers() { + return this.#inner.headers; + } + get status() { + return this.#inner.status; + } + get statusText() { + return this.#inner.statusText; + } + get ok() { + return 200 <= this.#inner.status && this.#inner.status <= 299; + } + get url() { + return this.#inner.url ?? ""; + } + get type() { + return this.#inner.type; + } + arrayBuffer() { + return this.bytes().buffer; + } + bytes() { + if (this.#body == null) return new Uint8Array(); + else if (typeof this.#body === "string") return textEncoder.encode(this.#body); + else return new Uint8Array(this.#body); + } + json() { + return JSON.parse(this.text()); + } + text() { + if (this.#body == null) return ""; + else if (typeof this.#body === "string") return this.#body; + else return textDecoder.decode(this.#body); + } +}; +var requestBaseSize = bsatnBaseSize({ types: [] }, HttpRequest.algebraicType); +var methods = /* @__PURE__ */ new Map([ + ["GET", { tag: "Get" }], + ["HEAD", { tag: "Head" }], + ["POST", { tag: "Post" }], + ["PUT", { tag: "Put" }], + ["DELETE", { tag: "Delete" }], + ["CONNECT", { tag: "Connect" }], + ["OPTIONS", { tag: "Options" }], + ["TRACE", { tag: "Trace" }], + ["PATCH", { tag: "Patch" }] +]); +function fetch(url, init = {}) { + const method = methods.get(init.method?.toUpperCase() ?? "GET") ?? { + tag: "Extension", + value: init.method + }; + const headers = { entries: headersToList(new Headers(init.headers)).flatMap(([k, v]) => Array.isArray(v) ? v.map((v2) => [k, v2]) : [[k, v]]).map(([name, value]) => ({ + name, + value: textEncoder.encode(value) + })) }; + const uri = "" + url; + const request = freeze2({ + method, + headers, + timeout: init.timeout, + uri, + version: { tag: "Http11" } + }); + const requestBuf = new BinaryWriter(requestBaseSize); + HttpRequest.serialize(requestBuf, request); + const body = init.body == null ? new Uint8Array() : typeof init.body === "string" ? init.body : new Uint8Array(init.body); + const [responseBuf, responseBody] = sys.procedure_http_request(requestBuf.getBuffer(), body); + const response = HttpResponse.deserialize(new BinaryReader(responseBuf)); + return SyncResponse[makeResponse](responseBody, { + type: "basic", + url: uri, + status: response.code, + statusText: (0, import_statuses.default)(response.code), + headers: new Headers(), + aborted: false + }); +} +freeze2(fetch); +var httpClient = freeze2({ fetch }); +function makeProcedureExport(ctx, opts, params, ret, fn) { + const name = opts?.name; + const procedureExport = (...args) => fn(...args); + procedureExport[exportContext] = ctx; + procedureExport[registerExport] = (ctx2, exportName) => { + registerProcedure(ctx2, name ?? exportName, params, ret, fn); + ctx2.functionExports.set(procedureExport, name ?? exportName); + }; + return procedureExport; +} +var TransactionCtxImpl = class TransactionCtx extends ReducerCtxImpl {}; +function registerProcedure(ctx, exportName, params, ret, fn, opts) { + ctx.defineFunction(exportName); + const paramsType = { elements: Object.entries(params).map(([n, c]) => ({ + name: n, + algebraicType: ctx.registerTypesRecursively("typeBuilder" in c ? c.typeBuilder : c).algebraicType + })) }; + const returnType = ctx.registerTypesRecursively(ret).algebraicType; + ctx.moduleDef.procedures.push({ + sourceName: exportName, + params: paramsType, + returnType, + visibility: FunctionVisibility.ClientCallable + }); + const { typespace } = ctx; + ctx.procedures.push({ + fn, + deserializeArgs: ProductType.makeDeserializer(paramsType, typespace), + serializeReturn: AlgebraicType.makeSerializer(returnType, typespace), + returnTypeBaseSize: bsatnBaseSize(typespace, returnType) + }); +} +function callProcedure(moduleCtx, id, sender, connectionId, timestamp, argsBuf, dbView) { + const { fn, deserializeArgs, serializeReturn, returnTypeBaseSize } = moduleCtx.procedures[id]; + const args = deserializeArgs(new BinaryReader(argsBuf)); + const ret = callUserFunction(fn, new ProcedureCtxImpl(sender, timestamp, connectionId, dbView), args); + const retBuf = new BinaryWriter(returnTypeBaseSize); + serializeReturn(retBuf, ret); + return retBuf.getBuffer(); +} +var ProcedureCtxImpl = class ProcedureCtx { + constructor(sender, timestamp, connectionId, dbView) { + this.sender = sender; + this.timestamp = timestamp; + this.connectionId = connectionId; + this.#dbView = dbView; + } + #identity; + #uuidCounter; + #random; + #dbView; + get identity() { + return this.#identity ??= new Identity(sys.identity()); + } + get random() { + return this.#random ??= makeRandom(this.timestamp); + } + get http() { + return httpClient; + } + withTx(body) { + const run = () => { + const timestamp = sys.procedure_start_mut_tx(); + try { + return body(new TransactionCtxImpl(this.sender, new Timestamp(timestamp), this.connectionId, this.#dbView())); + } catch (e) { + sys.procedure_abort_mut_tx(); + throw e; + } + }; + let res = run(); + try { + sys.procedure_commit_mut_tx(); + return res; + } catch {} + console.warn("committing anonymous transaction failed"); + res = run(); + try { + sys.procedure_commit_mut_tx(); + return res; + } catch (e) { + throw new Error("transaction retry failed again", { cause: e }); + } + } + newUuidV4() { + const bytes = this.random.fill(new Uint8Array(16)); + return Uuid.fromRandomBytesV4(bytes); + } + newUuidV7() { + const bytes = this.random.fill(new Uint8Array(4)); + const counter = this.#uuidCounter ??= { value: 0 }; + return Uuid.fromCounterV7(counter, this.timestamp, bytes); + } +}; +function makeReducerExport(ctx, opts, params, fn, lifecycle) { + const reducerExport = (...args) => fn(...args); + reducerExport[exportContext] = ctx; + reducerExport[registerExport] = (ctx2, exportName) => { + registerReducer(ctx2, exportName, params, fn, opts, lifecycle); + ctx2.functionExports.set(reducerExport, exportName); + }; + return reducerExport; +} +function registerReducer(ctx, exportName, params, fn, opts, lifecycle) { + ctx.defineFunction(exportName); + if (!(params instanceof RowBuilder)) params = new RowBuilder(params); + if (params.typeName === void 0) params.typeName = toPascalCase(exportName); + const ref = ctx.registerTypesRecursively(params); + const paramsType = ctx.resolveType(ref).value; + const isLifecycle = lifecycle != null; + ctx.moduleDef.reducers.push({ + sourceName: exportName, + params: paramsType, + visibility: FunctionVisibility.ClientCallable, + okReturnType: AlgebraicType.Product({ elements: [] }), + errReturnType: AlgebraicType.String + }); + if (opts?.name != null) ctx.moduleDef.explicitNames.entries.push({ + tag: "Function", + value: { + sourceName: exportName, + canonicalName: opts.name + } + }); + if (isLifecycle) ctx.moduleDef.lifeCycleReducers.push({ + lifecycleSpec: lifecycle, + functionName: exportName + }); + if (!fn.name) Object.defineProperty(fn, "name", { + value: exportName, + writable: false + }); + ctx.reducers.push(fn); +} +var SchemaInner = class extends ModuleContext { + schemaType; + existingFunctions = /* @__PURE__ */ new Set(); + reducers = []; + procedures = []; + views = []; + anonViews = []; + /** + * Maps ReducerExport objects to the name of the reducer. + * Used for resolving the reducers of scheduled tables. + */ + functionExports = /* @__PURE__ */ new Map(); + pendingSchedules = []; + constructor(getSchemaType) { + super(); + this.schemaType = getSchemaType(this); + } + defineFunction(name) { + if (this.existingFunctions.has(name)) throw new TypeError(`There is already a reducer or procedure with the name '${name}'`); + this.existingFunctions.add(name); + } + resolveSchedules() { + for (const { reducer, scheduleAtCol, tableName } of this.pendingSchedules) { + const functionName = this.functionExports.get(reducer()); + if (functionName === void 0) { + const msg = `Table ${tableName} defines a schedule, but it seems like the associated function was not exported.`; + throw new TypeError(msg); + } + this.moduleDef.schedules.push({ + sourceName: void 0, + tableName, + scheduleAtCol, + functionName + }); + } + } +}; +var Schema = class { + #ctx; + constructor(ctx) { + this.#ctx = ctx; + } + [moduleHooks](exports) { + const registeredSchema = this.#ctx; + for (const [name, moduleExport] of Object.entries(exports)) { + if (name === "default") continue; + if (!isModuleExport(moduleExport)) throw new TypeError("exporting something that is not a spacetime export"); + checkExportContext(moduleExport, registeredSchema); + moduleExport[registerExport](registeredSchema, name); + } + registeredSchema.resolveSchedules(); + return makeHooks(registeredSchema); + } + get schemaType() { + return this.#ctx.schemaType; + } + get moduleDef() { + return this.#ctx.moduleDef; + } + get typespace() { + return this.#ctx.typespace; + } + reducer(...args) { + let opts, params = {}, fn; + switch (args.length) { + case 1: + [fn] = args; + break; + case 2: { + let arg1; + [arg1, fn] = args; + if (typeof arg1.name === "string") opts = arg1; + else params = arg1; + break; + } + case 3: + [opts, params, fn] = args; + break; + } + return makeReducerExport(this.#ctx, opts, params, fn); + } + init(...args) { + let opts, fn; + switch (args.length) { + case 1: + [fn] = args; + break; + case 2: + [opts, fn] = args; + break; + } + return makeReducerExport(this.#ctx, opts, {}, fn, Lifecycle.Init); + } + clientConnected(...args) { + let opts, fn; + switch (args.length) { + case 1: + [fn] = args; + break; + case 2: + [opts, fn] = args; + break; + } + return makeReducerExport(this.#ctx, opts, {}, fn, Lifecycle.OnConnect); + } + clientDisconnected(...args) { + let opts, fn; + switch (args.length) { + case 1: + [fn] = args; + break; + case 2: + [opts, fn] = args; + break; + } + return makeReducerExport(this.#ctx, opts, {}, fn, Lifecycle.OnDisconnect); + } + view(opts, ret, fn) { + return makeViewExport(this.#ctx, opts, {}, ret, fn); + } + anonymousView(opts, ret, fn) { + return makeAnonViewExport(this.#ctx, opts, {}, ret, fn); + } + procedure(...args) { + let opts, params = {}, ret, fn; + switch (args.length) { + case 2: + [ret, fn] = args; + break; + case 3: { + let arg1; + [arg1, ret, fn] = args; + if (typeof arg1.name === "string") opts = arg1; + else params = arg1; + break; + } + case 4: + [opts, params, ret, fn] = args; + break; + } + return makeProcedureExport(this.#ctx, opts, params, ret, fn); + } + /** + * Bundle multiple reducers, procedures, etc into one value to export. + * The name they will be exported with is their corresponding key in the `exports` argument. + */ + exportGroup(exports) { + return { + [exportContext]: this.#ctx, + [registerExport](ctx, _exportName) { + for (const [exportName, moduleExport] of Object.entries(exports)) { + checkExportContext(moduleExport, ctx); + moduleExport[registerExport](ctx, exportName); + } + } + }; + } + clientVisibilityFilter = { sql: (filter) => ({ + [exportContext]: this.#ctx, + [registerExport](ctx, _exportName) { + ctx.moduleDef.rowLevelSecurity.push({ sql: filter }); + } + }) }; +}; +var registerExport = Symbol("SpacetimeDB.registerExport"); +var exportContext = Symbol("SpacetimeDB.exportContext"); +function isModuleExport(x) { + return (typeof x === "function" || typeof x === "object") && x !== null && registerExport in x; +} +function checkExportContext(exp, schema2) { + if (exp[exportContext] != null && exp[exportContext] !== schema2) throw new TypeError("multiple schemas are not supported"); +} +function schema(tables, moduleSettings) { + return new Schema(new SchemaInner((ctx2) => { + if (moduleSettings?.CASE_CONVERSION_POLICY != null) ctx2.setCaseConversionPolicy(moduleSettings.CASE_CONVERSION_POLICY); + const tableSchemas = {}; + for (const [accName, table2] of Object.entries(tables)) { + const tableDef = table2.tableDef(ctx2, accName); + tableSchemas[accName] = tableToSchema(accName, table2, tableDef); + ctx2.moduleDef.tables.push(tableDef); + if (table2.schedule) ctx2.pendingSchedules.push({ + ...table2.schedule, + tableName: tableDef.sourceName + }); + if (table2.tableName) ctx2.moduleDef.explicitNames.entries.push({ + tag: "Table", + value: { + sourceName: accName, + canonicalName: table2.tableName + } + }); + } + return { tables: tableSchemas }; + })); +} +var import_object_inspect = __toESM(require_object_inspect()); +var fmtLog = (...data) => data.map((x) => typeof x === "string" ? x : (0, import_object_inspect.default)(x)).join(" "); +var console_level_error = 0; +var console_level_warn = 1; +var console_level_info = 2; +var console_level_debug = 3; +var console_level_trace = 4; +var timerMap = /* @__PURE__ */ new Map(); +var console2 = { + __proto__: {}, + [Symbol.toStringTag]: "console", + assert: (condition = false, ...data) => { + if (!condition) sys.console_log(console_level_error, fmtLog(...data)); + }, + clear: () => {}, + debug: (...data) => { + sys.console_log(console_level_debug, fmtLog(...data)); + }, + error: (...data) => { + sys.console_log(console_level_error, fmtLog(...data)); + }, + info: (...data) => { + sys.console_log(console_level_info, fmtLog(...data)); + }, + log: (...data) => { + sys.console_log(console_level_info, fmtLog(...data)); + }, + table: (tabularData, _properties) => { + sys.console_log(console_level_info, fmtLog(tabularData)); + }, + trace: (...data) => { + sys.console_log(console_level_trace, fmtLog(...data)); + }, + warn: (...data) => { + sys.console_log(console_level_warn, fmtLog(...data)); + }, + dir: (_item, _options) => {}, + dirxml: (..._data) => {}, + count: (_label = "default") => {}, + countReset: (_label = "default") => {}, + group: (..._data) => {}, + groupCollapsed: (..._data) => {}, + groupEnd: () => {}, + time: (label = "default") => { + if (timerMap.has(label)) { + sys.console_log(console_level_warn, `Timer '${label}' already exists.`); + return; + } + timerMap.set(label, sys.console_timer_start(label)); + }, + timeLog: (label = "default", ...data) => { + sys.console_log(console_level_info, fmtLog(label, ...data)); + }, + timeEnd: (label = "default") => { + const spanId = timerMap.get(label); + if (spanId === void 0) { + sys.console_log(console_level_warn, `Timer '${label}' does not exist.`); + return; + } + sys.console_timer_end(spanId); + timerMap.delete(label); + }, + timeStamp: () => {}, + profile: () => {}, + profileEnd: () => {} +}; +globalThis.console = console2; + +//#endregion +//#region src/index.ts +const channel_kind = t.enum("ChannelKind", { + text: t.unit(), + voice: t.unit() +}); +const spacetimedb = schema({ + user: table({ + name: "user", + public: true + }, { + identity: t.identity().primaryKey(), + name: t.string().optional(), + online: t.bool(), + issuer: t.string().optional(), + subject: t.string().optional(), + username: t.string().optional(), + password: t.string().optional() + }), + server: table({ + name: "server", + public: true + }, { + id: t.u64().primaryKey().autoInc(), + name: t.string(), + owner: t.identity().optional() + }), + channel: table({ + name: "channel", + public: true, + indexes: [{ + accessor: "by_server_id", + algorithm: "btree", + columns: ["server_id"] + }] + }, { + id: t.u64().primaryKey().autoInc(), + server_id: t.u64(), + name: t.string(), + kind: channel_kind + }), + voice_state: table({ + name: "voice_state", + public: true, + indexes: [{ + accessor: "by_channel_id", + algorithm: "btree", + columns: ["channel_id"] + }] + }, { + identity: t.identity().primaryKey(), + channel_id: t.u64() + }), + sdp_offer: table({ + name: "sdp_offer", + public: true, + indexes: [{ + accessor: "by_receiver", + algorithm: "btree", + columns: ["receiver"] + }] + }, { + sender: t.identity(), + receiver: t.identity(), + sdp: t.string(), + channel_id: t.u64() + }), + sdp_answer: table({ + name: "sdp_answer", + public: true, + indexes: [{ + accessor: "by_receiver", + algorithm: "btree", + columns: ["receiver"] + }] + }, { + sender: t.identity(), + receiver: t.identity(), + sdp: t.string(), + channel_id: t.u64() + }), + ice_candidate: table({ + name: "ice_candidate", + public: true, + indexes: [{ + accessor: "by_receiver", + algorithm: "btree", + columns: ["receiver"] + }] + }, { + sender: t.identity(), + receiver: t.identity(), + candidate: t.string(), + channel_id: t.u64() + }), + thread: table({ + name: "thread", + public: true, + indexes: [{ + accessor: "by_channel_id", + algorithm: "btree", + columns: ["channel_id"] + }] + }, { + id: t.u64().primaryKey().autoInc(), + channel_id: t.u64(), + parent_message_id: t.u64().unique(), + name: t.string() + }), + message: table({ + name: "message", + public: true, + indexes: [{ + accessor: "by_channel_id", + algorithm: "btree", + columns: ["channel_id"] + }, { + accessor: "by_thread_id", + algorithm: "btree", + columns: ["thread_id"] + }] + }, { + id: t.u64().primaryKey().autoInc(), + sender: t.identity(), + sent: t.timestamp(), + text: t.string(), + channel_id: t.u64(), + thread_id: t.u64().optional() + }) +}); +function validateName(name) { + if (!name || name.trim().length === 0) throw new SenderError("Names must not be empty"); +} +const set_name = spacetimedb.reducer({ name: t.string() }, (ctx, { name }) => { + validateName(name); + const user = ctx.db.user.identity.find(ctx.sender); + if (!user) throw new SenderError("Cannot set name for unknown user"); + ctx.db.user.identity.update({ + ...user, + name + }); +}); +const register = spacetimedb.reducer({ + username: t.string(), + password: t.string() +}, (ctx, { username, password }) => { + validateName(username); + if (!password || password.length < 4) throw new SenderError("Password must be at least 4 characters"); + for (const u of ctx.db.user.iter()) if (u.username === username) throw new SenderError("Username already taken"); + const user = ctx.db.user.identity.find(ctx.sender); + if (user) ctx.db.user.identity.update({ + ...user, + username, + password, + name: user.name || username + }); + else ctx.db.user.insert({ + identity: ctx.sender, + username, + password, + name: username, + online: true, + issuer: void 0, + subject: void 0 + }); +}); +const login = spacetimedb.reducer({ + username: t.string(), + password: t.string() +}, (ctx, { username, password }) => { + let foundUser = null; + for (const u of ctx.db.user.iter()) if (u.username === username && u.password === password) { + foundUser = u; + break; + } + if (!foundUser) throw new SenderError("Invalid username or password"); + const currentIdentityUser = ctx.db.user.identity.find(ctx.sender); + if (currentIdentityUser && currentIdentityUser.identity.toHexString() !== foundUser.identity.toHexString()) ctx.db.user.identity.delete(ctx.sender); + if (foundUser.identity.toHexString() !== ctx.sender.toHexString()) { + ctx.db.user.identity.delete(foundUser.identity); + ctx.db.user.insert({ + ...foundUser, + identity: ctx.sender, + online: true + }); + } else ctx.db.user.identity.update({ + ...foundUser, + online: true + }); +}); +const create_server = spacetimedb.reducer({ name: t.string() }, (ctx, { name }) => { + validateName(name); + const user = ctx.db.user.identity.find(ctx.sender); + if (!user || !user.username && !user.subject) throw new SenderError("You must be logged in to create a server"); + const s = ctx.db.server.insert({ + id: 0n, + name, + owner: ctx.sender + }); + ctx.db.channel.insert({ + id: 0n, + server_id: s.id, + name: "general", + kind: { tag: "text" } + }); + ctx.db.channel.insert({ + id: 0n, + server_id: s.id, + name: "Voice General", + kind: { tag: "voice" } + }); +}); +const create_channel = spacetimedb.reducer({ + name: t.string(), + serverId: t.u64(), + isVoice: t.bool() +}, (ctx, { name, serverId, isVoice }) => { + validateName(name); + const user = ctx.db.user.identity.find(ctx.sender); + if (!user || !user.username && !user.subject) throw new SenderError("You must be logged in to create a channel"); + if (!ctx.db.server.id.find(serverId)) throw new SenderError("Server not found"); + ctx.db.channel.insert({ + id: 0n, + server_id: serverId, + name, + kind: isVoice ? { tag: "voice" } : { tag: "text" } + }); +}); +const join_voice = spacetimedb.reducer({ channelId: t.u64() }, (ctx, { channelId }) => { + const user = ctx.db.user.identity.find(ctx.sender); + if (!user || !user.username && !user.subject) throw new SenderError("You must be logged in to join voice"); + const chan = ctx.db.channel.id.find(channelId); + if (!chan || chan.kind.tag !== "voice") throw new SenderError("Invalid voice channel"); + const existing = ctx.db.voice_state.identity.find(ctx.sender); + if (existing) { + if (existing.channel_id !== channelId) { + clearSignalingForUser(ctx, ctx.sender); + ctx.db.voice_state.identity.update({ + identity: ctx.sender, + channel_id: channelId + }); + } + } else ctx.db.voice_state.insert({ + identity: ctx.sender, + channel_id: channelId + }); +}); +const leave_voice = spacetimedb.reducer((ctx) => { + ctx.db.voice_state.identity.delete(ctx.sender); + clearSignalingForUser(ctx, ctx.sender); +}); +const send_sdp_offer = spacetimedb.reducer({ + receiver: t.identity(), + sdp: t.string(), + channelId: t.u64() +}, (ctx, { receiver, sdp, channelId }) => { + ctx.db.sdp_offer.insert({ + sender: ctx.sender, + receiver, + sdp, + channel_id: channelId + }); +}); +const send_sdp_answer = spacetimedb.reducer({ + receiver: t.identity(), + sdp: t.string(), + channelId: t.u64() +}, (ctx, { receiver, sdp, channelId }) => { + ctx.db.sdp_answer.insert({ + sender: ctx.sender, + receiver, + sdp, + channel_id: channelId + }); +}); +const send_ice_candidate = spacetimedb.reducer({ + receiver: t.identity(), + candidate: t.string(), + channelId: t.u64() +}, (ctx, { receiver, candidate, channelId }) => { + ctx.db.ice_candidate.insert({ + sender: ctx.sender, + receiver, + candidate, + channel_id: channelId + }); +}); +function clearSignalingForUser(ctx, identity) { + const userOffers = ctx.db.sdp_offer.iter().filter((offer) => offer.sender.isEqual(identity) || offer.receiver.isEqual(identity)); + for (const offer of userOffers) ctx.db.sdp_offer.delete(offer.id); + const userAnswers = ctx.db.sdp_answer.iter().filter((answer) => answer.sender.isEqual(identity) || answer.receiver.isEqual(identity)); + for (const answer of userAnswers) ctx.db.sdp_answer.delete(answer.id); + const userCandidates = ctx.db.ice_candidate.iter().filter((candidate) => candidate.sender.isEqual(identity) || candidate.receiver.isEqual(identity)); + for (const candidate of userCandidates) ctx.db.ice_candidate.delete(candidate.id); +} +const create_thread = spacetimedb.reducer({ + name: t.string(), + channelId: t.u64(), + parentMessageId: t.u64() +}, (ctx, { name, channelId, parentMessageId }) => { + validateName(name); + const user = ctx.db.user.identity.find(ctx.sender); + if (!user || !user.username && !user.subject) throw new SenderError("You must be logged in to create a thread"); + if (!ctx.db.message.id.find(parentMessageId)) throw new SenderError("Parent message not found"); + ctx.db.thread.insert({ + id: 0n, + channel_id: channelId, + parent_message_id: parentMessageId, + name + }); +}); +const send_message = spacetimedb.reducer({ + text: t.string(), + channelId: t.u64(), + threadId: t.u64().optional() +}, (ctx, { text, channelId, threadId }) => { + if (!text || text.trim().length === 0) throw new SenderError("Messages must not be empty"); + const user = ctx.db.user.identity.find(ctx.sender); + if (!user || !user.username && !user.subject) throw new SenderError("You must be logged in to send messages"); + ctx.db.message.insert({ + id: 0n, + sender: ctx.sender, + text, + sent: ctx.timestamp, + channel_id: channelId, + thread_id: threadId + }); +}); +const init = spacetimedb.init((ctx) => { + let hasServers = false; + for (const _ of ctx.db.server.iter()) { + hasServers = true; + break; + } + if (!hasServers) { + const s = ctx.db.server.insert({ + id: 0n, + name: "Spacetime Community", + owner: void 0 + }); + ctx.db.channel.insert({ + id: 0n, + server_id: s.id, + name: "general", + kind: { tag: "text" } + }); + ctx.db.channel.insert({ + id: 0n, + server_id: s.id, + name: "Voice General", + kind: { tag: "voice" } + }); + } +}); +const onConnect = spacetimedb.clientConnected((ctx) => { + const user = ctx.db.user.identity.find(ctx.sender); + if (ctx.senderAuth.hasJWT && ctx.senderAuth.jwt) { + const jwt = ctx.senderAuth.jwt; + const issuer = jwt.issuer; + const subject = jwt.subject; + const payload = jwt.fullPayload; + const name = payload.name || payload.nickname || payload.preferred_username || payload.email; + if (user) ctx.db.user.identity.update({ + ...user, + online: true, + name: user.name || name, + issuer, + subject + }); + else ctx.db.user.insert({ + name, + identity: ctx.sender, + online: true, + issuer, + subject, + username: void 0, + password: void 0 + }); + } else if (user) ctx.db.user.identity.update({ + ...user, + online: true + }); +}); +const onDisconnect = spacetimedb.clientDisconnected((ctx) => { + const user = ctx.db.user.identity.find(ctx.sender); + if (user) ctx.db.user.identity.update({ + ...user, + online: false + }); + ctx.db.voice_state.identity.delete(ctx.sender); + clearSignalingForUser(ctx, ctx.sender); +}); + +//#endregion +export { create_channel, create_server, create_thread, spacetimedb as default, init, join_voice, leave_voice, login, onConnect, onDisconnect, register, send_ice_candidate, send_message, send_sdp_answer, send_sdp_offer, set_name }; +//# debugId=c9a38ab5-d5c5-4af9-81c8-7086063e3faf +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVuZGxlLmpzIiwibmFtZXMiOlsiX19jcmVhdGUiLCJfX2RlZlByb3AiLCJfX2dldE93blByb3BEZXNjIiwiX19nZXRPd25Qcm9wTmFtZXMiLCJfX2dldFByb3RvT2YiLCJfX2hhc093blByb3AiLCJfX2NvbW1vbkpTIiwiX19jb3B5UHJvcHMiLCJfX3RvRVNNIiwiI2Vuc3VyZSIsIiNtb2R1bGVEZWYiLCIjcmVnaXN0ZXJDb21wb3VuZFR5cGVSZWN1cnNpdmVseSIsIiNjb21wb3VuZFR5cGVzIiwiI2Zyb20iLCIjdG8iLCIjdXVpZENvdW50ZXIiLCIjc2VuZGVyQXV0aCIsIiNpZGVudGl0eSIsIiNyYW5kb20iLCIjc2NoZW1hIiwiI3JlZHVjZXJBcmdzRGVzZXJpYWxpemVycyIsIiNkYlZpZXciLCIjZGJWaWV3XyIsIiNyZWR1Y2VyQ3R4IiwiI3JlZHVjZXJDdHhfIiwiI2ZpbmFsaXphdGlvblJlZ2lzdHJ5IiwiI2lkIiwiI2RldGFjaCIsIiNib2R5IiwiI2lubmVyIiwiI2N0eCJdLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy8ucG5wbS9oZWFkZXJzLXBvbHlmaWxsQDQuMC4zL25vZGVfbW9kdWxlcy9oZWFkZXJzLXBvbHlmaWxsL2xpYi9pbmRleC5tanMiLCJub2RlX21vZHVsZXMvLnBucG0vc3BhY2V0aW1lZGJAMi4xLjAvbm9kZV9tb2R1bGVzL3NwYWNldGltZWRiL2Rpc3Qvc2VydmVyL2luZGV4Lm1qcyIsInNyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJ2YXIgX19jcmVhdGUgPSBPYmplY3QuY3JlYXRlO1xudmFyIF9fZGVmUHJvcCA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTtcbnZhciBfX2dldE93blByb3BEZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcjtcbnZhciBfX2dldE93blByb3BOYW1lcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzO1xudmFyIF9fZ2V0UHJvdG9PZiA9IE9iamVjdC5nZXRQcm90b3R5cGVPZjtcbnZhciBfX2hhc093blByb3AgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xudmFyIF9fY29tbW9uSlMgPSAoY2IsIG1vZCkgPT4gZnVuY3Rpb24gX19yZXF1aXJlKCkge1xuICByZXR1cm4gbW9kIHx8ICgwLCBjYltfX2dldE93blByb3BOYW1lcyhjYilbMF1dKSgobW9kID0geyBleHBvcnRzOiB7fSB9KS5leHBvcnRzLCBtb2QpLCBtb2QuZXhwb3J0cztcbn07XG52YXIgX19jb3B5UHJvcHMgPSAodG8sIGZyb20sIGV4Y2VwdCwgZGVzYykgPT4ge1xuICBpZiAoZnJvbSAmJiB0eXBlb2YgZnJvbSA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgZnJvbSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgZm9yIChsZXQga2V5IG9mIF9fZ2V0T3duUHJvcE5hbWVzKGZyb20pKVxuICAgICAgaWYgKCFfX2hhc093blByb3AuY2FsbCh0bywga2V5KSAmJiBrZXkgIT09IGV4Y2VwdClcbiAgICAgICAgX19kZWZQcm9wKHRvLCBrZXksIHsgZ2V0OiAoKSA9PiBmcm9tW2tleV0sIGVudW1lcmFibGU6ICEoZGVzYyA9IF9fZ2V0T3duUHJvcERlc2MoZnJvbSwga2V5KSkgfHwgZGVzYy5lbnVtZXJhYmxlIH0pO1xuICB9XG4gIHJldHVybiB0bztcbn07XG52YXIgX190b0VTTSA9IChtb2QsIGlzTm9kZU1vZGUsIHRhcmdldCkgPT4gKHRhcmdldCA9IG1vZCAhPSBudWxsID8gX19jcmVhdGUoX19nZXRQcm90b09mKG1vZCkpIDoge30sIF9fY29weVByb3BzKFxuICAvLyBJZiB0aGUgaW1wb3J0ZXIgaXMgaW4gbm9kZSBjb21wYXRpYmlsaXR5IG1vZGUgb3IgdGhpcyBpcyBub3QgYW4gRVNNXG4gIC8vIGZpbGUgdGhhdCBoYXMgYmVlbiBjb252ZXJ0ZWQgdG8gYSBDb21tb25KUyBmaWxlIHVzaW5nIGEgQmFiZWwtXG4gIC8vIGNvbXBhdGlibGUgdHJhbnNmb3JtIChpLmUuIFwiX19lc01vZHVsZVwiIGhhcyBub3QgYmVlbiBzZXQpLCB0aGVuIHNldFxuICAvLyBcImRlZmF1bHRcIiB0byB0aGUgQ29tbW9uSlMgXCJtb2R1bGUuZXhwb3J0c1wiIGZvciBub2RlIGNvbXBhdGliaWxpdHkuXG4gIGlzTm9kZU1vZGUgfHwgIW1vZCB8fCAhbW9kLl9fZXNNb2R1bGUgPyBfX2RlZlByb3AodGFyZ2V0LCBcImRlZmF1bHRcIiwgeyB2YWx1ZTogbW9kLCBlbnVtZXJhYmxlOiB0cnVlIH0pIDogdGFyZ2V0LFxuICBtb2RcbikpO1xuXG4vLyBub2RlX21vZHVsZXMvc2V0LWNvb2tpZS1wYXJzZXIvbGliL3NldC1jb29raWUuanNcbnZhciByZXF1aXJlX3NldF9jb29raWUgPSBfX2NvbW1vbkpTKHtcbiAgXCJub2RlX21vZHVsZXMvc2V0LWNvb2tpZS1wYXJzZXIvbGliL3NldC1jb29raWUuanNcIihleHBvcnRzLCBtb2R1bGUpIHtcbiAgICBcInVzZSBzdHJpY3RcIjtcbiAgICB2YXIgZGVmYXVsdFBhcnNlT3B0aW9ucyA9IHtcbiAgICAgIGRlY29kZVZhbHVlczogdHJ1ZSxcbiAgICAgIG1hcDogZmFsc2UsXG4gICAgICBzaWxlbnQ6IGZhbHNlXG4gICAgfTtcbiAgICBmdW5jdGlvbiBpc05vbkVtcHR5U3RyaW5nKHN0cikge1xuICAgICAgcmV0dXJuIHR5cGVvZiBzdHIgPT09IFwic3RyaW5nXCIgJiYgISFzdHIudHJpbSgpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBwYXJzZVN0cmluZyhzZXRDb29raWVWYWx1ZSwgb3B0aW9ucykge1xuICAgICAgdmFyIHBhcnRzID0gc2V0Q29va2llVmFsdWUuc3BsaXQoXCI7XCIpLmZpbHRlcihpc05vbkVtcHR5U3RyaW5nKTtcbiAgICAgIHZhciBuYW1lVmFsdWVQYWlyU3RyID0gcGFydHMuc2hpZnQoKTtcbiAgICAgIHZhciBwYXJzZWQgPSBwYXJzZU5hbWVWYWx1ZVBhaXIobmFtZVZhbHVlUGFpclN0cik7XG4gICAgICB2YXIgbmFtZSA9IHBhcnNlZC5uYW1lO1xuICAgICAgdmFyIHZhbHVlID0gcGFyc2VkLnZhbHVlO1xuICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgPyBPYmplY3QuYXNzaWduKHt9LCBkZWZhdWx0UGFyc2VPcHRpb25zLCBvcHRpb25zKSA6IGRlZmF1bHRQYXJzZU9wdGlvbnM7XG4gICAgICB0cnkge1xuICAgICAgICB2YWx1ZSA9IG9wdGlvbnMuZGVjb2RlVmFsdWVzID8gZGVjb2RlVVJJQ29tcG9uZW50KHZhbHVlKSA6IHZhbHVlO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgIFwic2V0LWNvb2tpZS1wYXJzZXIgZW5jb3VudGVyZWQgYW4gZXJyb3Igd2hpbGUgZGVjb2RpbmcgYSBjb29raWUgd2l0aCB2YWx1ZSAnXCIgKyB2YWx1ZSArIFwiJy4gU2V0IG9wdGlvbnMuZGVjb2RlVmFsdWVzIHRvIGZhbHNlIHRvIGRpc2FibGUgdGhpcyBmZWF0dXJlLlwiLFxuICAgICAgICAgIGVcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHZhciBjb29raWUgPSB7XG4gICAgICAgIG5hbWUsXG4gICAgICAgIHZhbHVlXG4gICAgICB9O1xuICAgICAgcGFydHMuZm9yRWFjaChmdW5jdGlvbihwYXJ0KSB7XG4gICAgICAgIHZhciBzaWRlcyA9IHBhcnQuc3BsaXQoXCI9XCIpO1xuICAgICAgICB2YXIga2V5ID0gc2lkZXMuc2hpZnQoKS50cmltTGVmdCgpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHZhciB2YWx1ZTIgPSBzaWRlcy5qb2luKFwiPVwiKTtcbiAgICAgICAgaWYgKGtleSA9PT0gXCJleHBpcmVzXCIpIHtcbiAgICAgICAgICBjb29raWUuZXhwaXJlcyA9IG5ldyBEYXRlKHZhbHVlMik7XG4gICAgICAgIH0gZWxzZSBpZiAoa2V5ID09PSBcIm1heC1hZ2VcIikge1xuICAgICAgICAgIGNvb2tpZS5tYXhBZ2UgPSBwYXJzZUludCh2YWx1ZTIsIDEwKTtcbiAgICAgICAgfSBlbHNlIGlmIChrZXkgPT09IFwic2VjdXJlXCIpIHtcbiAgICAgICAgICBjb29raWUuc2VjdXJlID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChrZXkgPT09IFwiaHR0cG9ubHlcIikge1xuICAgICAgICAgIGNvb2tpZS5odHRwT25seSA9IHRydWU7XG4gICAgICAgIH0gZWxzZSBpZiAoa2V5ID09PSBcInNhbWVzaXRlXCIpIHtcbiAgICAgICAgICBjb29raWUuc2FtZVNpdGUgPSB2YWx1ZTI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29va2llW2tleV0gPSB2YWx1ZTI7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGNvb2tpZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gcGFyc2VOYW1lVmFsdWVQYWlyKG5hbWVWYWx1ZVBhaXJTdHIpIHtcbiAgICAgIHZhciBuYW1lID0gXCJcIjtcbiAgICAgIHZhciB2YWx1ZSA9IFwiXCI7XG4gICAgICB2YXIgbmFtZVZhbHVlQXJyID0gbmFtZVZhbHVlUGFpclN0ci5zcGxpdChcIj1cIik7XG4gICAgICBpZiAobmFtZVZhbHVlQXJyLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgbmFtZSA9IG5hbWVWYWx1ZUFyci5zaGlmdCgpO1xuICAgICAgICB2YWx1ZSA9IG5hbWVWYWx1ZUFyci5qb2luKFwiPVwiKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhbHVlID0gbmFtZVZhbHVlUGFpclN0cjtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7IG5hbWUsIHZhbHVlIH07XG4gICAgfVxuICAgIGZ1bmN0aW9uIHBhcnNlKGlucHV0LCBvcHRpb25zKSB7XG4gICAgICBvcHRpb25zID0gb3B0aW9ucyA/IE9iamVjdC5hc3NpZ24oe30sIGRlZmF1bHRQYXJzZU9wdGlvbnMsIG9wdGlvbnMpIDogZGVmYXVsdFBhcnNlT3B0aW9ucztcbiAgICAgIGlmICghaW5wdXQpIHtcbiAgICAgICAgaWYgKCFvcHRpb25zLm1hcCkge1xuICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChpbnB1dC5oZWFkZXJzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQuaGVhZGVycy5nZXRTZXRDb29raWUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgIGlucHV0ID0gaW5wdXQuaGVhZGVycy5nZXRTZXRDb29raWUoKTtcbiAgICAgICAgfSBlbHNlIGlmIChpbnB1dC5oZWFkZXJzW1wic2V0LWNvb2tpZVwiXSkge1xuICAgICAgICAgIGlucHV0ID0gaW5wdXQuaGVhZGVyc1tcInNldC1jb29raWVcIl07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIHNjaCA9IGlucHV0LmhlYWRlcnNbT2JqZWN0LmtleXMoaW5wdXQuaGVhZGVycykuZmluZChmdW5jdGlvbihrZXkpIHtcbiAgICAgICAgICAgIHJldHVybiBrZXkudG9Mb3dlckNhc2UoKSA9PT0gXCJzZXQtY29va2llXCI7XG4gICAgICAgICAgfSldO1xuICAgICAgICAgIGlmICghc2NoICYmIGlucHV0LmhlYWRlcnMuY29va2llICYmICFvcHRpb25zLnNpbGVudCkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICBcIldhcm5pbmc6IHNldC1jb29raWUtcGFyc2VyIGFwcGVhcnMgdG8gaGF2ZSBiZWVuIGNhbGxlZCBvbiBhIHJlcXVlc3Qgb2JqZWN0LiBJdCBpcyBkZXNpZ25lZCB0byBwYXJzZSBTZXQtQ29va2llIGhlYWRlcnMgZnJvbSByZXNwb25zZXMsIG5vdCBDb29raWUgaGVhZGVycyBmcm9tIHJlcXVlc3RzLiBTZXQgdGhlIG9wdGlvbiB7c2lsZW50OiB0cnVlfSB0byBzdXBwcmVzcyB0aGlzIHdhcm5pbmcuXCJcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlucHV0ID0gc2NoO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoaW5wdXQpKSB7XG4gICAgICAgIGlucHV0ID0gW2lucHV0XTtcbiAgICAgIH1cbiAgICAgIG9wdGlvbnMgPSBvcHRpb25zID8gT2JqZWN0LmFzc2lnbih7fSwgZGVmYXVsdFBhcnNlT3B0aW9ucywgb3B0aW9ucykgOiBkZWZhdWx0UGFyc2VPcHRpb25zO1xuICAgICAgaWYgKCFvcHRpb25zLm1hcCkge1xuICAgICAgICByZXR1cm4gaW5wdXQuZmlsdGVyKGlzTm9uRW1wdHlTdHJpbmcpLm1hcChmdW5jdGlvbihzdHIpIHtcbiAgICAgICAgICByZXR1cm4gcGFyc2VTdHJpbmcoc3RyLCBvcHRpb25zKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgY29va2llcyA9IHt9O1xuICAgICAgICByZXR1cm4gaW5wdXQuZmlsdGVyKGlzTm9uRW1wdHlTdHJpbmcpLnJlZHVjZShmdW5jdGlvbihjb29raWVzMiwgc3RyKSB7XG4gICAgICAgICAgdmFyIGNvb2tpZSA9IHBhcnNlU3RyaW5nKHN0ciwgb3B0aW9ucyk7XG4gICAgICAgICAgY29va2llczJbY29va2llLm5hbWVdID0gY29va2llO1xuICAgICAgICAgIHJldHVybiBjb29raWVzMjtcbiAgICAgICAgfSwgY29va2llcyk7XG4gICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIHNwbGl0Q29va2llc1N0cmluZzIoY29va2llc1N0cmluZykge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY29va2llc1N0cmluZykpIHtcbiAgICAgICAgcmV0dXJuIGNvb2tpZXNTdHJpbmc7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIGNvb2tpZXNTdHJpbmcgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgICAgdmFyIGNvb2tpZXNTdHJpbmdzID0gW107XG4gICAgICB2YXIgcG9zID0gMDtcbiAgICAgIHZhciBzdGFydDtcbiAgICAgIHZhciBjaDtcbiAgICAgIHZhciBsYXN0Q29tbWE7XG4gICAgICB2YXIgbmV4dFN0YXJ0O1xuICAgICAgdmFyIGNvb2tpZXNTZXBhcmF0b3JGb3VuZDtcbiAgICAgIGZ1bmN0aW9uIHNraXBXaGl0ZXNwYWNlKCkge1xuICAgICAgICB3aGlsZSAocG9zIDwgY29va2llc1N0cmluZy5sZW5ndGggJiYgL1xccy8udGVzdChjb29raWVzU3RyaW5nLmNoYXJBdChwb3MpKSkge1xuICAgICAgICAgIHBvcyArPSAxO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwb3MgPCBjb29raWVzU3RyaW5nLmxlbmd0aDtcbiAgICAgIH1cbiAgICAgIGZ1bmN0aW9uIG5vdFNwZWNpYWxDaGFyKCkge1xuICAgICAgICBjaCA9IGNvb2tpZXNTdHJpbmcuY2hhckF0KHBvcyk7XG4gICAgICAgIHJldHVybiBjaCAhPT0gXCI9XCIgJiYgY2ggIT09IFwiO1wiICYmIGNoICE9PSBcIixcIjtcbiAgICAgIH1cbiAgICAgIHdoaWxlIChwb3MgPCBjb29raWVzU3RyaW5nLmxlbmd0aCkge1xuICAgICAgICBzdGFydCA9IHBvcztcbiAgICAgICAgY29va2llc1NlcGFyYXRvckZvdW5kID0gZmFsc2U7XG4gICAgICAgIHdoaWxlIChza2lwV2hpdGVzcGFjZSgpKSB7XG4gICAgICAgICAgY2ggPSBjb29raWVzU3RyaW5nLmNoYXJBdChwb3MpO1xuICAgICAgICAgIGlmIChjaCA9PT0gXCIsXCIpIHtcbiAgICAgICAgICAgIGxhc3RDb21tYSA9IHBvcztcbiAgICAgICAgICAgIHBvcyArPSAxO1xuICAgICAgICAgICAgc2tpcFdoaXRlc3BhY2UoKTtcbiAgICAgICAgICAgIG5leHRTdGFydCA9IHBvcztcbiAgICAgICAgICAgIHdoaWxlIChwb3MgPCBjb29raWVzU3RyaW5nLmxlbmd0aCAmJiBub3RTcGVjaWFsQ2hhcigpKSB7XG4gICAgICAgICAgICAgIHBvcyArPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHBvcyA8IGNvb2tpZXNTdHJpbmcubGVuZ3RoICYmIGNvb2tpZXNTdHJpbmcuY2hhckF0KHBvcykgPT09IFwiPVwiKSB7XG4gICAgICAgICAgICAgIGNvb2tpZXNTZXBhcmF0b3JGb3VuZCA9IHRydWU7XG4gICAgICAgICAgICAgIHBvcyA9IG5leHRTdGFydDtcbiAgICAgICAgICAgICAgY29va2llc1N0cmluZ3MucHVzaChjb29raWVzU3RyaW5nLnN1YnN0cmluZyhzdGFydCwgbGFzdENvbW1hKSk7XG4gICAgICAgICAgICAgIHN0YXJ0ID0gcG9zO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcG9zID0gbGFzdENvbW1hICsgMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcG9zICs9IDE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICghY29va2llc1NlcGFyYXRvckZvdW5kIHx8IHBvcyA+PSBjb29raWVzU3RyaW5nLmxlbmd0aCkge1xuICAgICAgICAgIGNvb2tpZXNTdHJpbmdzLnB1c2goY29va2llc1N0cmluZy5zdWJzdHJpbmcoc3RhcnQsIGNvb2tpZXNTdHJpbmcubGVuZ3RoKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBjb29raWVzU3RyaW5ncztcbiAgICB9XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBwYXJzZTtcbiAgICBtb2R1bGUuZXhwb3J0cy5wYXJzZSA9IHBhcnNlO1xuICAgIG1vZHVsZS5leHBvcnRzLnBhcnNlU3RyaW5nID0gcGFyc2VTdHJpbmc7XG4gICAgbW9kdWxlLmV4cG9ydHMuc3BsaXRDb29raWVzU3RyaW5nID0gc3BsaXRDb29raWVzU3RyaW5nMjtcbiAgfVxufSk7XG5cbi8vIHNyYy9IZWFkZXJzLnRzXG52YXIgaW1wb3J0X3NldF9jb29raWVfcGFyc2VyID0gX190b0VTTShyZXF1aXJlX3NldF9jb29raWUoKSk7XG5cbi8vIHNyYy91dGlscy9ub3JtYWxpemVIZWFkZXJOYW1lLnRzXG52YXIgSEVBREVSU19JTlZBTElEX0NIQVJBQ1RFUlMgPSAvW15hLXowLTlcXC0jJCUmJyorLl5fYHx+XS9pO1xuZnVuY3Rpb24gbm9ybWFsaXplSGVhZGVyTmFtZShuYW1lKSB7XG4gIGlmIChIRUFERVJTX0lOVkFMSURfQ0hBUkFDVEVSUy50ZXN0KG5hbWUpIHx8IG5hbWUudHJpbSgpID09PSBcIlwiKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgY2hhcmFjdGVyIGluIGhlYWRlciBmaWVsZCBuYW1lXCIpO1xuICB9XG4gIHJldHVybiBuYW1lLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xufVxuXG4vLyBzcmMvdXRpbHMvbm9ybWFsaXplSGVhZGVyVmFsdWUudHNcbnZhciBjaGFyQ29kZXNUb1JlbW92ZSA9IFtcbiAgU3RyaW5nLmZyb21DaGFyQ29kZSgxMCksXG4gIFN0cmluZy5mcm9tQ2hhckNvZGUoMTMpLFxuICBTdHJpbmcuZnJvbUNoYXJDb2RlKDkpLFxuICBTdHJpbmcuZnJvbUNoYXJDb2RlKDMyKVxuXTtcbnZhciBIRUFERVJfVkFMVUVfUkVNT1ZFX1JFR0VYUCA9IG5ldyBSZWdFeHAoXG4gIGAoXlske2NoYXJDb2Rlc1RvUmVtb3ZlLmpvaW4oXCJcIil9XXwkWyR7Y2hhckNvZGVzVG9SZW1vdmUuam9pbihcIlwiKX1dKWAsXG4gIFwiZ1wiXG4pO1xuZnVuY3Rpb24gbm9ybWFsaXplSGVhZGVyVmFsdWUodmFsdWUpIHtcbiAgY29uc3QgbmV4dFZhbHVlID0gdmFsdWUucmVwbGFjZShIRUFERVJfVkFMVUVfUkVNT1ZFX1JFR0VYUCwgXCJcIik7XG4gIHJldHVybiBuZXh0VmFsdWU7XG59XG5cbi8vIHNyYy91dGlscy9pc1ZhbGlkSGVhZGVyTmFtZS50c1xuZnVuY3Rpb24gaXNWYWxpZEhlYWRlck5hbWUodmFsdWUpIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodmFsdWUubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBjaGFyYWN0ZXIgPSB2YWx1ZS5jaGFyQ29kZUF0KGkpO1xuICAgIGlmIChjaGFyYWN0ZXIgPiAxMjcgfHwgIWlzVG9rZW4oY2hhcmFjdGVyKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIGlzVG9rZW4odmFsdWUpIHtcbiAgcmV0dXJuICFbXG4gICAgMTI3LFxuICAgIDMyLFxuICAgIFwiKFwiLFxuICAgIFwiKVwiLFxuICAgIFwiPFwiLFxuICAgIFwiPlwiLFxuICAgIFwiQFwiLFxuICAgIFwiLFwiLFxuICAgIFwiO1wiLFxuICAgIFwiOlwiLFxuICAgIFwiXFxcXFwiLFxuICAgICdcIicsXG4gICAgXCIvXCIsXG4gICAgXCJbXCIsXG4gICAgXCJdXCIsXG4gICAgXCI/XCIsXG4gICAgXCI9XCIsXG4gICAgXCJ7XCIsXG4gICAgXCJ9XCJcbiAgXS5pbmNsdWRlcyh2YWx1ZSk7XG59XG5cbi8vIHNyYy91dGlscy9pc1ZhbGlkSGVhZGVyVmFsdWUudHNcbmZ1bmN0aW9uIGlzVmFsaWRIZWFkZXJWYWx1ZSh2YWx1ZSkge1xuICBpZiAodHlwZW9mIHZhbHVlICE9PSBcInN0cmluZ1wiKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICh2YWx1ZS50cmltKCkgIT09IHZhbHVlKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBjaGFyYWN0ZXIgPSB2YWx1ZS5jaGFyQ29kZUF0KGkpO1xuICAgIGlmIChcbiAgICAgIC8vIE5VTC5cbiAgICAgIGNoYXJhY3RlciA9PT0gMCB8fCAvLyBIVFRQIG5ld2xpbmUgYnl0ZXMuXG4gICAgICBjaGFyYWN0ZXIgPT09IDEwIHx8IGNoYXJhY3RlciA9PT0gMTNcbiAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbi8vIHNyYy9IZWFkZXJzLnRzXG52YXIgTk9STUFMSVpFRF9IRUFERVJTID0gU3ltYm9sKFwibm9ybWFsaXplZEhlYWRlcnNcIik7XG52YXIgUkFXX0hFQURFUl9OQU1FUyA9IFN5bWJvbChcInJhd0hlYWRlck5hbWVzXCIpO1xudmFyIEhFQURFUl9WQUxVRV9ERUxJTUlURVIgPSBcIiwgXCI7XG52YXIgX2EsIF9iLCBfYztcbnZhciBIZWFkZXJzID0gY2xhc3MgX0hlYWRlcnMge1xuICBjb25zdHJ1Y3Rvcihpbml0KSB7XG4gICAgLy8gTm9ybWFsaXplZCBoZWFkZXIge1wibmFtZVwiOlwiYSwgYlwifSBzdG9yYWdlLlxuICAgIHRoaXNbX2FdID0ge307XG4gICAgLy8gS2VlcHMgdGhlIG1hcHBpbmcgYmV0d2VlbiB0aGUgcmF3IGhlYWRlciBuYW1lXG4gICAgLy8gYW5kIHRoZSBub3JtYWxpemVkIGhlYWRlciBuYW1lIHRvIGVhc2UgdGhlIGxvb2t1cC5cbiAgICB0aGlzW19iXSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7XG4gICAgdGhpc1tfY10gPSBcIkhlYWRlcnNcIjtcbiAgICBpZiAoW1wiSGVhZGVyc1wiLCBcIkhlYWRlcnNQb2x5ZmlsbFwiXS5pbmNsdWRlcyhpbml0Py5jb25zdHJ1Y3Rvci5uYW1lKSB8fCBpbml0IGluc3RhbmNlb2YgX0hlYWRlcnMgfHwgdHlwZW9mIGdsb2JhbFRoaXMuSGVhZGVycyAhPT0gXCJ1bmRlZmluZWRcIiAmJiBpbml0IGluc3RhbmNlb2YgZ2xvYmFsVGhpcy5IZWFkZXJzKSB7XG4gICAgICBjb25zdCBpbml0aWFsSGVhZGVycyA9IGluaXQ7XG4gICAgICBpbml0aWFsSGVhZGVycy5mb3JFYWNoKCh2YWx1ZSwgbmFtZSkgPT4ge1xuICAgICAgICB0aGlzLmFwcGVuZChuYW1lLCB2YWx1ZSk7XG4gICAgICB9LCB0aGlzKTtcbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoaW5pdCkpIHtcbiAgICAgIGluaXQuZm9yRWFjaCgoW25hbWUsIHZhbHVlXSkgPT4ge1xuICAgICAgICB0aGlzLmFwcGVuZChcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUuam9pbihIRUFERVJfVkFMVUVfREVMSU1JVEVSKSA6IHZhbHVlXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKGluaXQpIHtcbiAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGluaXQpLmZvckVhY2goKG5hbWUpID0+IHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBpbml0W25hbWVdO1xuICAgICAgICB0aGlzLmFwcGVuZChcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUuam9pbihIRUFERVJfVkFMVUVfREVMSU1JVEVSKSA6IHZhbHVlXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbiAgWyhfYSA9IE5PUk1BTElaRURfSEVBREVSUywgX2IgPSBSQVdfSEVBREVSX05BTUVTLCBfYyA9IFN5bWJvbC50b1N0cmluZ1RhZywgU3ltYm9sLml0ZXJhdG9yKV0oKSB7XG4gICAgcmV0dXJuIHRoaXMuZW50cmllcygpO1xuICB9XG4gICprZXlzKCkge1xuICAgIGZvciAoY29uc3QgW25hbWVdIG9mIHRoaXMuZW50cmllcygpKSB7XG4gICAgICB5aWVsZCBuYW1lO1xuICAgIH1cbiAgfVxuICAqdmFsdWVzKCkge1xuICAgIGZvciAoY29uc3QgWywgdmFsdWVdIG9mIHRoaXMuZW50cmllcygpKSB7XG4gICAgICB5aWVsZCB2YWx1ZTtcbiAgICB9XG4gIH1cbiAgKmVudHJpZXMoKSB7XG4gICAgbGV0IHNvcnRlZEtleXMgPSBPYmplY3Qua2V5cyh0aGlzW05PUk1BTElaRURfSEVBREVSU10pLnNvcnQoXG4gICAgICAoYSwgYikgPT4gYS5sb2NhbGVDb21wYXJlKGIpXG4gICAgKTtcbiAgICBmb3IgKGNvbnN0IG5hbWUgb2Ygc29ydGVkS2V5cykge1xuICAgICAgaWYgKG5hbWUgPT09IFwic2V0LWNvb2tpZVwiKSB7XG4gICAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgdGhpcy5nZXRTZXRDb29raWUoKSkge1xuICAgICAgICAgIHlpZWxkIFtuYW1lLCB2YWx1ZV07XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHlpZWxkIFtuYW1lLCB0aGlzLmdldChuYW1lKV07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgYm9vbGVhbiBzdGF0aW5nIHdoZXRoZXIgYSBgSGVhZGVyc2Agb2JqZWN0IGNvbnRhaW5zIGEgY2VydGFpbiBoZWFkZXIuXG4gICAqL1xuICBoYXMobmFtZSkge1xuICAgIGlmICghaXNWYWxpZEhlYWRlck5hbWUobmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYEludmFsaWQgaGVhZGVyIG5hbWUgXCIke25hbWV9XCJgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXNbTk9STUFMSVpFRF9IRUFERVJTXS5oYXNPd25Qcm9wZXJ0eShub3JtYWxpemVIZWFkZXJOYW1lKG5hbWUpKTtcbiAgfVxuICAvKipcbiAgICogUmV0dXJucyBhIGBCeXRlU3RyaW5nYCBzZXF1ZW5jZSBvZiBhbGwgdGhlIHZhbHVlcyBvZiBhIGhlYWRlciB3aXRoIGEgZ2l2ZW4gbmFtZS5cbiAgICovXG4gIGdldChuYW1lKSB7XG4gICAgaWYgKCFpc1ZhbGlkSGVhZGVyTmFtZShuYW1lKSkge1xuICAgICAgdGhyb3cgVHlwZUVycm9yKGBJbnZhbGlkIGhlYWRlciBuYW1lIFwiJHtuYW1lfVwiYCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzW05PUk1BTElaRURfSEVBREVSU11bbm9ybWFsaXplSGVhZGVyTmFtZShuYW1lKV0gPz8gbnVsbDtcbiAgfVxuICAvKipcbiAgICogU2V0cyBhIG5ldyB2YWx1ZSBmb3IgYW4gZXhpc3RpbmcgaGVhZGVyIGluc2lkZSBhIGBIZWFkZXJzYCBvYmplY3QsIG9yIGFkZHMgdGhlIGhlYWRlciBpZiBpdCBkb2VzIG5vdCBhbHJlYWR5IGV4aXN0LlxuICAgKi9cbiAgc2V0KG5hbWUsIHZhbHVlKSB7XG4gICAgaWYgKCFpc1ZhbGlkSGVhZGVyTmFtZShuYW1lKSB8fCAhaXNWYWxpZEhlYWRlclZhbHVlKHZhbHVlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBub3JtYWxpemVkTmFtZSA9IG5vcm1hbGl6ZUhlYWRlck5hbWUobmFtZSk7XG4gICAgY29uc3Qgbm9ybWFsaXplZFZhbHVlID0gbm9ybWFsaXplSGVhZGVyVmFsdWUodmFsdWUpO1xuICAgIHRoaXNbTk9STUFMSVpFRF9IRUFERVJTXVtub3JtYWxpemVkTmFtZV0gPSBub3JtYWxpemVIZWFkZXJWYWx1ZShub3JtYWxpemVkVmFsdWUpO1xuICAgIHRoaXNbUkFXX0hFQURFUl9OQU1FU10uc2V0KG5vcm1hbGl6ZWROYW1lLCBuYW1lKTtcbiAgfVxuICAvKipcbiAgICogQXBwZW5kcyBhIG5ldyB2YWx1ZSBvbnRvIGFuIGV4aXN0aW5nIGhlYWRlciBpbnNpZGUgYSBgSGVhZGVyc2Agb2JqZWN0LCBvciBhZGRzIHRoZSBoZWFkZXIgaWYgaXQgZG9lcyBub3QgYWxyZWFkeSBleGlzdC5cbiAgICovXG4gIGFwcGVuZChuYW1lLCB2YWx1ZSkge1xuICAgIGlmICghaXNWYWxpZEhlYWRlck5hbWUobmFtZSkgfHwgIWlzVmFsaWRIZWFkZXJWYWx1ZSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgbm9ybWFsaXplZE5hbWUgPSBub3JtYWxpemVIZWFkZXJOYW1lKG5hbWUpO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRWYWx1ZSA9IG5vcm1hbGl6ZUhlYWRlclZhbHVlKHZhbHVlKTtcbiAgICBsZXQgcmVzb2x2ZWRWYWx1ZSA9IHRoaXMuaGFzKG5vcm1hbGl6ZWROYW1lKSA/IGAke3RoaXMuZ2V0KG5vcm1hbGl6ZWROYW1lKX0sICR7bm9ybWFsaXplZFZhbHVlfWAgOiBub3JtYWxpemVkVmFsdWU7XG4gICAgdGhpcy5zZXQobmFtZSwgcmVzb2x2ZWRWYWx1ZSk7XG4gIH1cbiAgLyoqXG4gICAqIERlbGV0ZXMgYSBoZWFkZXIgZnJvbSB0aGUgYEhlYWRlcnNgIG9iamVjdC5cbiAgICovXG4gIGRlbGV0ZShuYW1lKSB7XG4gICAgaWYgKCFpc1ZhbGlkSGVhZGVyTmFtZShuYW1lKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuaGFzKG5hbWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG5vcm1hbGl6ZWROYW1lID0gbm9ybWFsaXplSGVhZGVyTmFtZShuYW1lKTtcbiAgICBkZWxldGUgdGhpc1tOT1JNQUxJWkVEX0hFQURFUlNdW25vcm1hbGl6ZWROYW1lXTtcbiAgICB0aGlzW1JBV19IRUFERVJfTkFNRVNdLmRlbGV0ZShub3JtYWxpemVkTmFtZSk7XG4gIH1cbiAgLyoqXG4gICAqIFRyYXZlcnNlcyB0aGUgYEhlYWRlcnNgIG9iamVjdCxcbiAgICogY2FsbGluZyB0aGUgZ2l2ZW4gY2FsbGJhY2sgZm9yIGVhY2ggaGVhZGVyLlxuICAgKi9cbiAgZm9yRWFjaChjYWxsYmFjaywgdGhpc0FyZykge1xuICAgIGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiB0aGlzLmVudHJpZXMoKSkge1xuICAgICAgY2FsbGJhY2suY2FsbCh0aGlzQXJnLCB2YWx1ZSwgbmFtZSwgdGhpcyk7XG4gICAgfVxuICB9XG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIHZhbHVlc1xuICAgKiBvZiBhbGwgU2V0LUNvb2tpZSBoZWFkZXJzIGFzc29jaWF0ZWRcbiAgICogd2l0aCBhIHJlc3BvbnNlXG4gICAqL1xuICBnZXRTZXRDb29raWUoKSB7XG4gICAgY29uc3Qgc2V0Q29va2llSGVhZGVyID0gdGhpcy5nZXQoXCJzZXQtY29va2llXCIpO1xuICAgIGlmIChzZXRDb29raWVIZWFkZXIgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgaWYgKHNldENvb2tpZUhlYWRlciA9PT0gXCJcIikge1xuICAgICAgcmV0dXJuIFtcIlwiXTtcbiAgICB9XG4gICAgcmV0dXJuICgwLCBpbXBvcnRfc2V0X2Nvb2tpZV9wYXJzZXIuc3BsaXRDb29raWVzU3RyaW5nKShzZXRDb29raWVIZWFkZXIpO1xuICB9XG59O1xuXG4vLyBzcmMvZ2V0UmF3SGVhZGVycy50c1xuZnVuY3Rpb24gZ2V0UmF3SGVhZGVycyhoZWFkZXJzKSB7XG4gIGNvbnN0IHJhd0hlYWRlcnMgPSB7fTtcbiAgZm9yIChjb25zdCBbbmFtZSwgdmFsdWVdIG9mIGhlYWRlcnMuZW50cmllcygpKSB7XG4gICAgcmF3SGVhZGVyc1toZWFkZXJzW1JBV19IRUFERVJfTkFNRVNdLmdldChuYW1lKV0gPSB2YWx1ZTtcbiAgfVxuICByZXR1cm4gcmF3SGVhZGVycztcbn1cblxuLy8gc3JjL3RyYW5zZm9ybWVycy9oZWFkZXJzVG9MaXN0LnRzXG5mdW5jdGlvbiBoZWFkZXJzVG9MaXN0KGhlYWRlcnMpIHtcbiAgY29uc3QgaGVhZGVyc0xpc3QgPSBbXTtcbiAgaGVhZGVycy5mb3JFYWNoKCh2YWx1ZSwgbmFtZSkgPT4ge1xuICAgIGNvbnN0IHJlc29sdmVkVmFsdWUgPSB2YWx1ZS5pbmNsdWRlcyhcIixcIikgPyB2YWx1ZS5zcGxpdChcIixcIikubWFwKCh2YWx1ZTIpID0+IHZhbHVlMi50cmltKCkpIDogdmFsdWU7XG4gICAgaGVhZGVyc0xpc3QucHVzaChbbmFtZSwgcmVzb2x2ZWRWYWx1ZV0pO1xuICB9KTtcbiAgcmV0dXJuIGhlYWRlcnNMaXN0O1xufVxuXG4vLyBzcmMvdHJhbnNmb3JtZXJzL2hlYWRlcnNUb1N0cmluZy50c1xuZnVuY3Rpb24gaGVhZGVyc1RvU3RyaW5nKGhlYWRlcnMpIHtcbiAgY29uc3QgbGlzdCA9IGhlYWRlcnNUb0xpc3QoaGVhZGVycyk7XG4gIGNvbnN0IGxpbmVzID0gbGlzdC5tYXAoKFtuYW1lLCB2YWx1ZV0pID0+IHtcbiAgICBjb25zdCB2YWx1ZXMgPSBbXS5jb25jYXQodmFsdWUpO1xuICAgIHJldHVybiBgJHtuYW1lfTogJHt2YWx1ZXMuam9pbihcIiwgXCIpfWA7XG4gIH0pO1xuICByZXR1cm4gbGluZXMuam9pbihcIlxcclxcblwiKTtcbn1cblxuLy8gc3JjL3RyYW5zZm9ybWVycy9oZWFkZXJzVG9PYmplY3QudHNcbnZhciBzaW5nbGVWYWx1ZUhlYWRlcnMgPSBbXCJ1c2VyLWFnZW50XCJdO1xuZnVuY3Rpb24gaGVhZGVyc1RvT2JqZWN0KGhlYWRlcnMpIHtcbiAgY29uc3QgaGVhZGVyc09iamVjdCA9IHt9O1xuICBoZWFkZXJzLmZvckVhY2goKHZhbHVlLCBuYW1lKSA9PiB7XG4gICAgY29uc3QgaXNNdWx0aVZhbHVlID0gIXNpbmdsZVZhbHVlSGVhZGVycy5pbmNsdWRlcyhuYW1lLnRvTG93ZXJDYXNlKCkpICYmIHZhbHVlLmluY2x1ZGVzKFwiLFwiKTtcbiAgICBoZWFkZXJzT2JqZWN0W25hbWVdID0gaXNNdWx0aVZhbHVlID8gdmFsdWUuc3BsaXQoXCIsXCIpLm1hcCgocykgPT4gcy50cmltKCkpIDogdmFsdWU7XG4gIH0pO1xuICByZXR1cm4gaGVhZGVyc09iamVjdDtcbn1cblxuLy8gc3JjL3RyYW5zZm9ybWVycy9zdHJpbmdUb0hlYWRlcnMudHNcbmZ1bmN0aW9uIHN0cmluZ1RvSGVhZGVycyhzdHIpIHtcbiAgY29uc3QgbGluZXMgPSBzdHIudHJpbSgpLnNwbGl0KC9bXFxyXFxuXSsvKTtcbiAgcmV0dXJuIGxpbmVzLnJlZHVjZSgoaGVhZGVycywgbGluZSkgPT4ge1xuICAgIGlmIChsaW5lLnRyaW0oKSA9PT0gXCJcIikge1xuICAgICAgcmV0dXJuIGhlYWRlcnM7XG4gICAgfVxuICAgIGNvbnN0IHBhcnRzID0gbGluZS5zcGxpdChcIjogXCIpO1xuICAgIGNvbnN0IG5hbWUgPSBwYXJ0cy5zaGlmdCgpO1xuICAgIGNvbnN0IHZhbHVlID0gcGFydHMuam9pbihcIjogXCIpO1xuICAgIGhlYWRlcnMuYXBwZW5kKG5hbWUsIHZhbHVlKTtcbiAgICByZXR1cm4gaGVhZGVycztcbiAgfSwgbmV3IEhlYWRlcnMoKSk7XG59XG5cbi8vIHNyYy90cmFuc2Zvcm1lcnMvbGlzdFRvSGVhZGVycy50c1xuZnVuY3Rpb24gbGlzdFRvSGVhZGVycyhsaXN0KSB7XG4gIGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycygpO1xuICBsaXN0LmZvckVhY2goKFtuYW1lLCB2YWx1ZV0pID0+IHtcbiAgICBjb25zdCB2YWx1ZXMgPSBbXS5jb25jYXQodmFsdWUpO1xuICAgIHZhbHVlcy5mb3JFYWNoKCh2YWx1ZTIpID0+IHtcbiAgICAgIGhlYWRlcnMuYXBwZW5kKG5hbWUsIHZhbHVlMik7XG4gICAgfSk7XG4gIH0pO1xuICByZXR1cm4gaGVhZGVycztcbn1cblxuLy8gc3JjL3RyYW5zZm9ybWVycy9yZWR1Y2VIZWFkZXJzT2JqZWN0LnRzXG5mdW5jdGlvbiByZWR1Y2VIZWFkZXJzT2JqZWN0KGhlYWRlcnMsIHJlZHVjZXIsIGluaXRpYWxTdGF0ZSkge1xuICByZXR1cm4gT2JqZWN0LmtleXMoaGVhZGVycykucmVkdWNlKChuZXh0SGVhZGVycywgbmFtZSkgPT4ge1xuICAgIHJldHVybiByZWR1Y2VyKG5leHRIZWFkZXJzLCBuYW1lLCBoZWFkZXJzW25hbWVdKTtcbiAgfSwgaW5pdGlhbFN0YXRlKTtcbn1cblxuLy8gc3JjL3RyYW5zZm9ybWVycy9vYmplY3RUb0hlYWRlcnMudHNcbmZ1bmN0aW9uIG9iamVjdFRvSGVhZGVycyhoZWFkZXJzT2JqZWN0KSB7XG4gIHJldHVybiByZWR1Y2VIZWFkZXJzT2JqZWN0KFxuICAgIGhlYWRlcnNPYmplY3QsXG4gICAgKGhlYWRlcnMsIG5hbWUsIHZhbHVlKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZXMgPSBbXS5jb25jYXQodmFsdWUpLmZpbHRlcihCb29sZWFuKTtcbiAgICAgIHZhbHVlcy5mb3JFYWNoKCh2YWx1ZTIpID0+IHtcbiAgICAgICAgaGVhZGVycy5hcHBlbmQobmFtZSwgdmFsdWUyKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGhlYWRlcnM7XG4gICAgfSxcbiAgICBuZXcgSGVhZGVycygpXG4gICk7XG59XG5cbi8vIHNyYy90cmFuc2Zvcm1lcnMvZmxhdHRlbkhlYWRlcnNMaXN0LnRzXG5mdW5jdGlvbiBmbGF0dGVuSGVhZGVyc0xpc3QobGlzdCkge1xuICByZXR1cm4gbGlzdC5tYXAoKFtuYW1lLCB2YWx1ZXNdKSA9PiB7XG4gICAgcmV0dXJuIFtuYW1lLCBbXS5jb25jYXQodmFsdWVzKS5qb2luKFwiLCBcIildO1xuICB9KTtcbn1cblxuLy8gc3JjL3RyYW5zZm9ybWVycy9mbGF0dGVuSGVhZGVyc09iamVjdC50c1xuZnVuY3Rpb24gZmxhdHRlbkhlYWRlcnNPYmplY3QoaGVhZGVyc09iamVjdCkge1xuICByZXR1cm4gcmVkdWNlSGVhZGVyc09iamVjdChcbiAgICBoZWFkZXJzT2JqZWN0LFxuICAgIChoZWFkZXJzLCBuYW1lLCB2YWx1ZSkgPT4ge1xuICAgICAgaGVhZGVyc1tuYW1lXSA9IFtdLmNvbmNhdCh2YWx1ZSkuam9pbihcIiwgXCIpO1xuICAgICAgcmV0dXJuIGhlYWRlcnM7XG4gICAgfSxcbiAgICB7fVxuICApO1xufVxuZXhwb3J0IHtcbiAgSGVhZGVycyxcbiAgZmxhdHRlbkhlYWRlcnNMaXN0LFxuICBmbGF0dGVuSGVhZGVyc09iamVjdCxcbiAgZ2V0UmF3SGVhZGVycyxcbiAgaGVhZGVyc1RvTGlzdCxcbiAgaGVhZGVyc1RvT2JqZWN0LFxuICBoZWFkZXJzVG9TdHJpbmcsXG4gIGxpc3RUb0hlYWRlcnMsXG4gIG9iamVjdFRvSGVhZGVycyxcbiAgcmVkdWNlSGVhZGVyc09iamVjdCxcbiAgc3RyaW5nVG9IZWFkZXJzXG59O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXgubWpzLm1hcCIsImltcG9ydCAqIGFzIF9zeXNjYWxsczJfMCBmcm9tICdzcGFjZXRpbWU6c3lzQDIuMCc7XG5pbXBvcnQgeyBtb2R1bGVIb29rcyB9IGZyb20gJ3NwYWNldGltZTpzeXNAMi4wJztcbmltcG9ydCB7IGhlYWRlcnNUb0xpc3QsIEhlYWRlcnMgfSBmcm9tICdoZWFkZXJzLXBvbHlmaWxsJztcblxudHlwZW9mIGdsb2JhbFRoaXMhPT1cInVuZGVmaW5lZFwiJiYoKGdsb2JhbFRoaXMuZ2xvYmFsPWdsb2JhbFRoaXMuZ2xvYmFsfHxnbG9iYWxUaGlzKSwoZ2xvYmFsVGhpcy53aW5kb3c9Z2xvYmFsVGhpcy53aW5kb3d8fGdsb2JhbFRoaXMpKTtcbnZhciBfX2NyZWF0ZSA9IE9iamVjdC5jcmVhdGU7XG52YXIgX19kZWZQcm9wID0gT2JqZWN0LmRlZmluZVByb3BlcnR5O1xudmFyIF9fZ2V0T3duUHJvcERlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yO1xudmFyIF9fZ2V0T3duUHJvcE5hbWVzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXM7XG52YXIgX19nZXRQcm90b09mID0gT2JqZWN0LmdldFByb3RvdHlwZU9mO1xudmFyIF9faGFzT3duUHJvcCA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgX19lc20gPSAoZm4sIHJlcykgPT4gZnVuY3Rpb24gX19pbml0KCkge1xuICByZXR1cm4gZm4gJiYgKHJlcyA9ICgwLCBmbltfX2dldE93blByb3BOYW1lcyhmbilbMF1dKShmbiA9IDApKSwgcmVzO1xufTtcbnZhciBfX2NvbW1vbkpTID0gKGNiLCBtb2QpID0+IGZ1bmN0aW9uIF9fcmVxdWlyZSgpIHtcbiAgcmV0dXJuIG1vZCB8fCAoMCwgY2JbX19nZXRPd25Qcm9wTmFtZXMoY2IpWzBdXSkoKG1vZCA9IHsgZXhwb3J0czoge30gfSkuZXhwb3J0cywgbW9kKSwgbW9kLmV4cG9ydHM7XG59O1xudmFyIF9fZXhwb3J0ID0gKHRhcmdldCwgYWxsKSA9PiB7XG4gIGZvciAodmFyIG5hbWUgaW4gYWxsKVxuICAgIF9fZGVmUHJvcCh0YXJnZXQsIG5hbWUsIHsgZ2V0OiBhbGxbbmFtZV0sIGVudW1lcmFibGU6IHRydWUgfSk7XG59O1xudmFyIF9fY29weVByb3BzID0gKHRvLCBmcm9tLCBleGNlcHQsIGRlc2MpID0+IHtcbiAgaWYgKGZyb20gJiYgdHlwZW9mIGZyb20gPT09IFwib2JqZWN0XCIgfHwgdHlwZW9mIGZyb20gPT09IFwiZnVuY3Rpb25cIikge1xuICAgIGZvciAobGV0IGtleSBvZiBfX2dldE93blByb3BOYW1lcyhmcm9tKSlcbiAgICAgIGlmICghX19oYXNPd25Qcm9wLmNhbGwodG8sIGtleSkgJiYga2V5ICE9PSBleGNlcHQpXG4gICAgICAgIF9fZGVmUHJvcCh0bywga2V5LCB7IGdldDogKCkgPT4gZnJvbVtrZXldLCBlbnVtZXJhYmxlOiAhKGRlc2MgPSBfX2dldE93blByb3BEZXNjKGZyb20sIGtleSkpIHx8IGRlc2MuZW51bWVyYWJsZSB9KTtcbiAgfVxuICByZXR1cm4gdG87XG59O1xudmFyIF9fdG9FU00gPSAobW9kLCBpc05vZGVNb2RlLCB0YXJnZXQpID0+ICh0YXJnZXQgPSBtb2QgIT0gbnVsbCA/IF9fY3JlYXRlKF9fZ2V0UHJvdG9PZihtb2QpKSA6IHt9LCBfX2NvcHlQcm9wcyhcbiAgLy8gSWYgdGhlIGltcG9ydGVyIGlzIGluIG5vZGUgY29tcGF0aWJpbGl0eSBtb2RlIG9yIHRoaXMgaXMgbm90IGFuIEVTTVxuICAvLyBmaWxlIHRoYXQgaGFzIGJlZW4gY29udmVydGVkIHRvIGEgQ29tbW9uSlMgZmlsZSB1c2luZyBhIEJhYmVsLVxuICAvLyBjb21wYXRpYmxlIHRyYW5zZm9ybSAoaS5lLiBcIl9fZXNNb2R1bGVcIiBoYXMgbm90IGJlZW4gc2V0KSwgdGhlbiBzZXRcbiAgLy8gXCJkZWZhdWx0XCIgdG8gdGhlIENvbW1vbkpTIFwibW9kdWxlLmV4cG9ydHNcIiBmb3Igbm9kZSBjb21wYXRpYmlsaXR5LlxuICBfX2RlZlByb3AodGFyZ2V0LCBcImRlZmF1bHRcIiwgeyB2YWx1ZTogbW9kLCBlbnVtZXJhYmxlOiB0cnVlIH0pICxcbiAgbW9kXG4pKTtcbnZhciBfX3RvQ29tbW9uSlMgPSAobW9kKSA9PiBfX2NvcHlQcm9wcyhfX2RlZlByb3Aoe30sIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pLCBtb2QpO1xuXG4vLyAuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vYmFzZTY0LWpzQDEuNS4xL25vZGVfbW9kdWxlcy9iYXNlNjQtanMvaW5kZXguanNcbnZhciByZXF1aXJlX2Jhc2U2NF9qcyA9IF9fY29tbW9uSlMoe1xuICBcIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9iYXNlNjQtanNAMS41LjEvbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9pbmRleC5qc1wiKGV4cG9ydHMpIHtcbiAgICBleHBvcnRzLmJ5dGVMZW5ndGggPSBieXRlTGVuZ3RoO1xuICAgIGV4cG9ydHMudG9CeXRlQXJyYXkgPSB0b0J5dGVBcnJheTtcbiAgICBleHBvcnRzLmZyb21CeXRlQXJyYXkgPSBmcm9tQnl0ZUFycmF5MjtcbiAgICB2YXIgbG9va3VwID0gW107XG4gICAgdmFyIHJldkxvb2t1cCA9IFtdO1xuICAgIHZhciBBcnIgPSB0eXBlb2YgVWludDhBcnJheSAhPT0gXCJ1bmRlZmluZWRcIiA/IFVpbnQ4QXJyYXkgOiBBcnJheTtcbiAgICB2YXIgY29kZSA9IFwiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrL1wiO1xuICAgIGZvciAoaSA9IDAsIGxlbiA9IGNvZGUubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgIGxvb2t1cFtpXSA9IGNvZGVbaV07XG4gICAgICByZXZMb29rdXBbY29kZS5jaGFyQ29kZUF0KGkpXSA9IGk7XG4gICAgfVxuICAgIHZhciBpO1xuICAgIHZhciBsZW47XG4gICAgcmV2TG9va3VwW1wiLVwiLmNoYXJDb2RlQXQoMCldID0gNjI7XG4gICAgcmV2TG9va3VwW1wiX1wiLmNoYXJDb2RlQXQoMCldID0gNjM7XG4gICAgZnVuY3Rpb24gZ2V0TGVucyhiNjQpIHtcbiAgICAgIHZhciBsZW4yID0gYjY0Lmxlbmd0aDtcbiAgICAgIGlmIChsZW4yICUgNCA+IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBzdHJpbmcuIExlbmd0aCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNFwiKTtcbiAgICAgIH1cbiAgICAgIHZhciB2YWxpZExlbiA9IGI2NC5pbmRleE9mKFwiPVwiKTtcbiAgICAgIGlmICh2YWxpZExlbiA9PT0gLTEpIHZhbGlkTGVuID0gbGVuMjtcbiAgICAgIHZhciBwbGFjZUhvbGRlcnNMZW4gPSB2YWxpZExlbiA9PT0gbGVuMiA/IDAgOiA0IC0gdmFsaWRMZW4gJSA0O1xuICAgICAgcmV0dXJuIFt2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuXTtcbiAgICB9XG4gICAgZnVuY3Rpb24gYnl0ZUxlbmd0aChiNjQpIHtcbiAgICAgIHZhciBsZW5zID0gZ2V0TGVucyhiNjQpO1xuICAgICAgdmFyIHZhbGlkTGVuID0gbGVuc1swXTtcbiAgICAgIHZhciBwbGFjZUhvbGRlcnNMZW4gPSBsZW5zWzFdO1xuICAgICAgcmV0dXJuICh2YWxpZExlbiArIHBsYWNlSG9sZGVyc0xlbikgKiAzIC8gNCAtIHBsYWNlSG9sZGVyc0xlbjtcbiAgICB9XG4gICAgZnVuY3Rpb24gX2J5dGVMZW5ndGgoYjY0LCB2YWxpZExlbiwgcGxhY2VIb2xkZXJzTGVuKSB7XG4gICAgICByZXR1cm4gKHZhbGlkTGVuICsgcGxhY2VIb2xkZXJzTGVuKSAqIDMgLyA0IC0gcGxhY2VIb2xkZXJzTGVuO1xuICAgIH1cbiAgICBmdW5jdGlvbiB0b0J5dGVBcnJheShiNjQpIHtcbiAgICAgIHZhciB0bXA7XG4gICAgICB2YXIgbGVucyA9IGdldExlbnMoYjY0KTtcbiAgICAgIHZhciB2YWxpZExlbiA9IGxlbnNbMF07XG4gICAgICB2YXIgcGxhY2VIb2xkZXJzTGVuID0gbGVuc1sxXTtcbiAgICAgIHZhciBhcnIgPSBuZXcgQXJyKF9ieXRlTGVuZ3RoKGI2NCwgdmFsaWRMZW4sIHBsYWNlSG9sZGVyc0xlbikpO1xuICAgICAgdmFyIGN1ckJ5dGUgPSAwO1xuICAgICAgdmFyIGxlbjIgPSBwbGFjZUhvbGRlcnNMZW4gPiAwID8gdmFsaWRMZW4gLSA0IDogdmFsaWRMZW47XG4gICAgICB2YXIgaTI7XG4gICAgICBmb3IgKGkyID0gMDsgaTIgPCBsZW4yOyBpMiArPSA0KSB7XG4gICAgICAgIHRtcCA9IHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpMildIDw8IDE4IHwgcmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkyICsgMSldIDw8IDEyIHwgcmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkyICsgMildIDw8IDYgfCByZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaTIgKyAzKV07XG4gICAgICAgIGFycltjdXJCeXRlKytdID0gdG1wID4+IDE2ICYgMjU1O1xuICAgICAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCA+PiA4ICYgMjU1O1xuICAgICAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDI1NTtcbiAgICAgIH1cbiAgICAgIGlmIChwbGFjZUhvbGRlcnNMZW4gPT09IDIpIHtcbiAgICAgICAgdG1wID0gcmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkyKV0gPDwgMiB8IHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpMiArIDEpXSA+PiA0O1xuICAgICAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDI1NTtcbiAgICAgIH1cbiAgICAgIGlmIChwbGFjZUhvbGRlcnNMZW4gPT09IDEpIHtcbiAgICAgICAgdG1wID0gcmV2TG9va3VwW2I2NC5jaGFyQ29kZUF0KGkyKV0gPDwgMTAgfCByZXZMb29rdXBbYjY0LmNoYXJDb2RlQXQoaTIgKyAxKV0gPDwgNCB8IHJldkxvb2t1cFtiNjQuY2hhckNvZGVBdChpMiArIDIpXSA+PiAyO1xuICAgICAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCA+PiA4ICYgMjU1O1xuICAgICAgICBhcnJbY3VyQnl0ZSsrXSA9IHRtcCAmIDI1NTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhcnI7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHRyaXBsZXRUb0Jhc2U2NChudW0pIHtcbiAgICAgIHJldHVybiBsb29rdXBbbnVtID4+IDE4ICYgNjNdICsgbG9va3VwW251bSA+PiAxMiAmIDYzXSArIGxvb2t1cFtudW0gPj4gNiAmIDYzXSArIGxvb2t1cFtudW0gJiA2M107XG4gICAgfVxuICAgIGZ1bmN0aW9uIGVuY29kZUNodW5rKHVpbnQ4LCBzdGFydCwgZW5kKSB7XG4gICAgICB2YXIgdG1wO1xuICAgICAgdmFyIG91dHB1dCA9IFtdO1xuICAgICAgZm9yICh2YXIgaTIgPSBzdGFydDsgaTIgPCBlbmQ7IGkyICs9IDMpIHtcbiAgICAgICAgdG1wID0gKHVpbnQ4W2kyXSA8PCAxNiAmIDE2NzExNjgwKSArICh1aW50OFtpMiArIDFdIDw8IDggJiA2NTI4MCkgKyAodWludDhbaTIgKyAyXSAmIDI1NSk7XG4gICAgICAgIG91dHB1dC5wdXNoKHRyaXBsZXRUb0Jhc2U2NCh0bXApKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBvdXRwdXQuam9pbihcIlwiKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gZnJvbUJ5dGVBcnJheTIodWludDgpIHtcbiAgICAgIHZhciB0bXA7XG4gICAgICB2YXIgbGVuMiA9IHVpbnQ4Lmxlbmd0aDtcbiAgICAgIHZhciBleHRyYUJ5dGVzID0gbGVuMiAlIDM7XG4gICAgICB2YXIgcGFydHMgPSBbXTtcbiAgICAgIHZhciBtYXhDaHVua0xlbmd0aCA9IDE2MzgzO1xuICAgICAgZm9yICh2YXIgaTIgPSAwLCBsZW4yMiA9IGxlbjIgLSBleHRyYUJ5dGVzOyBpMiA8IGxlbjIyOyBpMiArPSBtYXhDaHVua0xlbmd0aCkge1xuICAgICAgICBwYXJ0cy5wdXNoKGVuY29kZUNodW5rKHVpbnQ4LCBpMiwgaTIgKyBtYXhDaHVua0xlbmd0aCA+IGxlbjIyID8gbGVuMjIgOiBpMiArIG1heENodW5rTGVuZ3RoKSk7XG4gICAgICB9XG4gICAgICBpZiAoZXh0cmFCeXRlcyA9PT0gMSkge1xuICAgICAgICB0bXAgPSB1aW50OFtsZW4yIC0gMV07XG4gICAgICAgIHBhcnRzLnB1c2goXG4gICAgICAgICAgbG9va3VwW3RtcCA+PiAyXSArIGxvb2t1cFt0bXAgPDwgNCAmIDYzXSArIFwiPT1cIlxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChleHRyYUJ5dGVzID09PSAyKSB7XG4gICAgICAgIHRtcCA9ICh1aW50OFtsZW4yIC0gMl0gPDwgOCkgKyB1aW50OFtsZW4yIC0gMV07XG4gICAgICAgIHBhcnRzLnB1c2goXG4gICAgICAgICAgbG9va3VwW3RtcCA+PiAxMF0gKyBsb29rdXBbdG1wID4+IDQgJiA2M10gKyBsb29rdXBbdG1wIDw8IDIgJiA2M10gKyBcIj1cIlxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHBhcnRzLmpvaW4oXCJcIik7XG4gICAgfVxuICB9XG59KTtcblxuLy8gLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3N0YXR1c2VzQDIuMC4yL25vZGVfbW9kdWxlcy9zdGF0dXNlcy9jb2Rlcy5qc29uXG52YXIgcmVxdWlyZV9jb2RlcyA9IF9fY29tbW9uSlMoe1xuICBcIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9zdGF0dXNlc0AyLjAuMi9ub2RlX21vZHVsZXMvc3RhdHVzZXMvY29kZXMuanNvblwiKGV4cG9ydHMsIG1vZHVsZSkge1xuICAgIG1vZHVsZS5leHBvcnRzID0ge1xuICAgICAgXCIxMDBcIjogXCJDb250aW51ZVwiLFxuICAgICAgXCIxMDFcIjogXCJTd2l0Y2hpbmcgUHJvdG9jb2xzXCIsXG4gICAgICBcIjEwMlwiOiBcIlByb2Nlc3NpbmdcIixcbiAgICAgIFwiMTAzXCI6IFwiRWFybHkgSGludHNcIixcbiAgICAgIFwiMjAwXCI6IFwiT0tcIixcbiAgICAgIFwiMjAxXCI6IFwiQ3JlYXRlZFwiLFxuICAgICAgXCIyMDJcIjogXCJBY2NlcHRlZFwiLFxuICAgICAgXCIyMDNcIjogXCJOb24tQXV0aG9yaXRhdGl2ZSBJbmZvcm1hdGlvblwiLFxuICAgICAgXCIyMDRcIjogXCJObyBDb250ZW50XCIsXG4gICAgICBcIjIwNVwiOiBcIlJlc2V0IENvbnRlbnRcIixcbiAgICAgIFwiMjA2XCI6IFwiUGFydGlhbCBDb250ZW50XCIsXG4gICAgICBcIjIwN1wiOiBcIk11bHRpLVN0YXR1c1wiLFxuICAgICAgXCIyMDhcIjogXCJBbHJlYWR5IFJlcG9ydGVkXCIsXG4gICAgICBcIjIyNlwiOiBcIklNIFVzZWRcIixcbiAgICAgIFwiMzAwXCI6IFwiTXVsdGlwbGUgQ2hvaWNlc1wiLFxuICAgICAgXCIzMDFcIjogXCJNb3ZlZCBQZXJtYW5lbnRseVwiLFxuICAgICAgXCIzMDJcIjogXCJGb3VuZFwiLFxuICAgICAgXCIzMDNcIjogXCJTZWUgT3RoZXJcIixcbiAgICAgIFwiMzA0XCI6IFwiTm90IE1vZGlmaWVkXCIsXG4gICAgICBcIjMwNVwiOiBcIlVzZSBQcm94eVwiLFxuICAgICAgXCIzMDdcIjogXCJUZW1wb3JhcnkgUmVkaXJlY3RcIixcbiAgICAgIFwiMzA4XCI6IFwiUGVybWFuZW50IFJlZGlyZWN0XCIsXG4gICAgICBcIjQwMFwiOiBcIkJhZCBSZXF1ZXN0XCIsXG4gICAgICBcIjQwMVwiOiBcIlVuYXV0aG9yaXplZFwiLFxuICAgICAgXCI0MDJcIjogXCJQYXltZW50IFJlcXVpcmVkXCIsXG4gICAgICBcIjQwM1wiOiBcIkZvcmJpZGRlblwiLFxuICAgICAgXCI0MDRcIjogXCJOb3QgRm91bmRcIixcbiAgICAgIFwiNDA1XCI6IFwiTWV0aG9kIE5vdCBBbGxvd2VkXCIsXG4gICAgICBcIjQwNlwiOiBcIk5vdCBBY2NlcHRhYmxlXCIsXG4gICAgICBcIjQwN1wiOiBcIlByb3h5IEF1dGhlbnRpY2F0aW9uIFJlcXVpcmVkXCIsXG4gICAgICBcIjQwOFwiOiBcIlJlcXVlc3QgVGltZW91dFwiLFxuICAgICAgXCI0MDlcIjogXCJDb25mbGljdFwiLFxuICAgICAgXCI0MTBcIjogXCJHb25lXCIsXG4gICAgICBcIjQxMVwiOiBcIkxlbmd0aCBSZXF1aXJlZFwiLFxuICAgICAgXCI0MTJcIjogXCJQcmVjb25kaXRpb24gRmFpbGVkXCIsXG4gICAgICBcIjQxM1wiOiBcIlBheWxvYWQgVG9vIExhcmdlXCIsXG4gICAgICBcIjQxNFwiOiBcIlVSSSBUb28gTG9uZ1wiLFxuICAgICAgXCI0MTVcIjogXCJVbnN1cHBvcnRlZCBNZWRpYSBUeXBlXCIsXG4gICAgICBcIjQxNlwiOiBcIlJhbmdlIE5vdCBTYXRpc2ZpYWJsZVwiLFxuICAgICAgXCI0MTdcIjogXCJFeHBlY3RhdGlvbiBGYWlsZWRcIixcbiAgICAgIFwiNDE4XCI6IFwiSSdtIGEgVGVhcG90XCIsXG4gICAgICBcIjQyMVwiOiBcIk1pc2RpcmVjdGVkIFJlcXVlc3RcIixcbiAgICAgIFwiNDIyXCI6IFwiVW5wcm9jZXNzYWJsZSBFbnRpdHlcIixcbiAgICAgIFwiNDIzXCI6IFwiTG9ja2VkXCIsXG4gICAgICBcIjQyNFwiOiBcIkZhaWxlZCBEZXBlbmRlbmN5XCIsXG4gICAgICBcIjQyNVwiOiBcIlRvbyBFYXJseVwiLFxuICAgICAgXCI0MjZcIjogXCJVcGdyYWRlIFJlcXVpcmVkXCIsXG4gICAgICBcIjQyOFwiOiBcIlByZWNvbmRpdGlvbiBSZXF1aXJlZFwiLFxuICAgICAgXCI0MjlcIjogXCJUb28gTWFueSBSZXF1ZXN0c1wiLFxuICAgICAgXCI0MzFcIjogXCJSZXF1ZXN0IEhlYWRlciBGaWVsZHMgVG9vIExhcmdlXCIsXG4gICAgICBcIjQ1MVwiOiBcIlVuYXZhaWxhYmxlIEZvciBMZWdhbCBSZWFzb25zXCIsXG4gICAgICBcIjUwMFwiOiBcIkludGVybmFsIFNlcnZlciBFcnJvclwiLFxuICAgICAgXCI1MDFcIjogXCJOb3QgSW1wbGVtZW50ZWRcIixcbiAgICAgIFwiNTAyXCI6IFwiQmFkIEdhdGV3YXlcIixcbiAgICAgIFwiNTAzXCI6IFwiU2VydmljZSBVbmF2YWlsYWJsZVwiLFxuICAgICAgXCI1MDRcIjogXCJHYXRld2F5IFRpbWVvdXRcIixcbiAgICAgIFwiNTA1XCI6IFwiSFRUUCBWZXJzaW9uIE5vdCBTdXBwb3J0ZWRcIixcbiAgICAgIFwiNTA2XCI6IFwiVmFyaWFudCBBbHNvIE5lZ290aWF0ZXNcIixcbiAgICAgIFwiNTA3XCI6IFwiSW5zdWZmaWNpZW50IFN0b3JhZ2VcIixcbiAgICAgIFwiNTA4XCI6IFwiTG9vcCBEZXRlY3RlZFwiLFxuICAgICAgXCI1MDlcIjogXCJCYW5kd2lkdGggTGltaXQgRXhjZWVkZWRcIixcbiAgICAgIFwiNTEwXCI6IFwiTm90IEV4dGVuZGVkXCIsXG4gICAgICBcIjUxMVwiOiBcIk5ldHdvcmsgQXV0aGVudGljYXRpb24gUmVxdWlyZWRcIlxuICAgIH07XG4gIH1cbn0pO1xuXG4vLyAuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vc3RhdHVzZXNAMi4wLjIvbm9kZV9tb2R1bGVzL3N0YXR1c2VzL2luZGV4LmpzXG52YXIgcmVxdWlyZV9zdGF0dXNlcyA9IF9fY29tbW9uSlMoe1xuICBcIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9zdGF0dXNlc0AyLjAuMi9ub2RlX21vZHVsZXMvc3RhdHVzZXMvaW5kZXguanNcIihleHBvcnRzLCBtb2R1bGUpIHtcbiAgICB2YXIgY29kZXMgPSByZXF1aXJlX2NvZGVzKCk7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBzdGF0dXMyO1xuICAgIHN0YXR1czIubWVzc2FnZSA9IGNvZGVzO1xuICAgIHN0YXR1czIuY29kZSA9IGNyZWF0ZU1lc3NhZ2VUb1N0YXR1c0NvZGVNYXAoY29kZXMpO1xuICAgIHN0YXR1czIuY29kZXMgPSBjcmVhdGVTdGF0dXNDb2RlTGlzdChjb2Rlcyk7XG4gICAgc3RhdHVzMi5yZWRpcmVjdCA9IHtcbiAgICAgIDMwMDogdHJ1ZSxcbiAgICAgIDMwMTogdHJ1ZSxcbiAgICAgIDMwMjogdHJ1ZSxcbiAgICAgIDMwMzogdHJ1ZSxcbiAgICAgIDMwNTogdHJ1ZSxcbiAgICAgIDMwNzogdHJ1ZSxcbiAgICAgIDMwODogdHJ1ZVxuICAgIH07XG4gICAgc3RhdHVzMi5lbXB0eSA9IHtcbiAgICAgIDIwNDogdHJ1ZSxcbiAgICAgIDIwNTogdHJ1ZSxcbiAgICAgIDMwNDogdHJ1ZVxuICAgIH07XG4gICAgc3RhdHVzMi5yZXRyeSA9IHtcbiAgICAgIDUwMjogdHJ1ZSxcbiAgICAgIDUwMzogdHJ1ZSxcbiAgICAgIDUwNDogdHJ1ZVxuICAgIH07XG4gICAgZnVuY3Rpb24gY3JlYXRlTWVzc2FnZVRvU3RhdHVzQ29kZU1hcChjb2RlczIpIHtcbiAgICAgIHZhciBtYXAgPSB7fTtcbiAgICAgIE9iamVjdC5rZXlzKGNvZGVzMikuZm9yRWFjaChmdW5jdGlvbiBmb3JFYWNoQ29kZShjb2RlKSB7XG4gICAgICAgIHZhciBtZXNzYWdlID0gY29kZXMyW2NvZGVdO1xuICAgICAgICB2YXIgc3RhdHVzMyA9IE51bWJlcihjb2RlKTtcbiAgICAgICAgbWFwW21lc3NhZ2UudG9Mb3dlckNhc2UoKV0gPSBzdGF0dXMzO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gbWFwO1xuICAgIH1cbiAgICBmdW5jdGlvbiBjcmVhdGVTdGF0dXNDb2RlTGlzdChjb2RlczIpIHtcbiAgICAgIHJldHVybiBPYmplY3Qua2V5cyhjb2RlczIpLm1hcChmdW5jdGlvbiBtYXBDb2RlKGNvZGUpIHtcbiAgICAgICAgcmV0dXJuIE51bWJlcihjb2RlKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBmdW5jdGlvbiBnZXRTdGF0dXNDb2RlKG1lc3NhZ2UpIHtcbiAgICAgIHZhciBtc2cgPSBtZXNzYWdlLnRvTG93ZXJDYXNlKCk7XG4gICAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzdGF0dXMyLmNvZGUsIG1zZykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHN0YXR1cyBtZXNzYWdlOiBcIicgKyBtZXNzYWdlICsgJ1wiJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gc3RhdHVzMi5jb2RlW21zZ107XG4gICAgfVxuICAgIGZ1bmN0aW9uIGdldFN0YXR1c01lc3NhZ2UoY29kZSkge1xuICAgICAgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc3RhdHVzMi5tZXNzYWdlLCBjb2RlKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJpbnZhbGlkIHN0YXR1cyBjb2RlOiBcIiArIGNvZGUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHN0YXR1czIubWVzc2FnZVtjb2RlXTtcbiAgICB9XG4gICAgZnVuY3Rpb24gc3RhdHVzMihjb2RlKSB7XG4gICAgICBpZiAodHlwZW9mIGNvZGUgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgcmV0dXJuIGdldFN0YXR1c01lc3NhZ2UoY29kZSk7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIGNvZGUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImNvZGUgbXVzdCBiZSBhIG51bWJlciBvciBzdHJpbmdcIik7XG4gICAgICB9XG4gICAgICB2YXIgbiA9IHBhcnNlSW50KGNvZGUsIDEwKTtcbiAgICAgIGlmICghaXNOYU4obikpIHtcbiAgICAgICAgcmV0dXJuIGdldFN0YXR1c01lc3NhZ2Uobik7XG4gICAgICB9XG4gICAgICByZXR1cm4gZ2V0U3RhdHVzQ29kZShjb2RlKTtcbiAgICB9XG4gIH1cbn0pO1xuXG4vLyBzcmMvdXRpbC1zdHViLnRzXG52YXIgdXRpbF9zdHViX2V4cG9ydHMgPSB7fTtcbl9fZXhwb3J0KHV0aWxfc3R1Yl9leHBvcnRzLCB7XG4gIGluc3BlY3Q6ICgpID0+IGluc3BlY3Rcbn0pO1xudmFyIGluc3BlY3Q7XG52YXIgaW5pdF91dGlsX3N0dWIgPSBfX2VzbSh7XG4gIFwic3JjL3V0aWwtc3R1Yi50c1wiKCkge1xuICAgIGluc3BlY3QgPSB7fTtcbiAgfVxufSk7XG5cbi8vIC4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9vYmplY3QtaW5zcGVjdEAxLjEzLjQvbm9kZV9tb2R1bGVzL29iamVjdC1pbnNwZWN0L3V0aWwuaW5zcGVjdC5qc1xudmFyIHJlcXVpcmVfdXRpbF9pbnNwZWN0ID0gX19jb21tb25KUyh7XG4gIFwiLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL29iamVjdC1pbnNwZWN0QDEuMTMuNC9ub2RlX21vZHVsZXMvb2JqZWN0LWluc3BlY3QvdXRpbC5pbnNwZWN0LmpzXCIoZXhwb3J0cywgbW9kdWxlKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSAoaW5pdF91dGlsX3N0dWIoKSwgX190b0NvbW1vbkpTKHV0aWxfc3R1Yl9leHBvcnRzKSkuaW5zcGVjdDtcbiAgfVxufSk7XG5cbi8vIC4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9vYmplY3QtaW5zcGVjdEAxLjEzLjQvbm9kZV9tb2R1bGVzL29iamVjdC1pbnNwZWN0L2luZGV4LmpzXG52YXIgcmVxdWlyZV9vYmplY3RfaW5zcGVjdCA9IF9fY29tbW9uSlMoe1xuICBcIi4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9vYmplY3QtaW5zcGVjdEAxLjEzLjQvbm9kZV9tb2R1bGVzL29iamVjdC1pbnNwZWN0L2luZGV4LmpzXCIoZXhwb3J0cywgbW9kdWxlKSB7XG4gICAgdmFyIGhhc01hcCA9IHR5cGVvZiBNYXAgPT09IFwiZnVuY3Rpb25cIiAmJiBNYXAucHJvdG90eXBlO1xuICAgIHZhciBtYXBTaXplRGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IgJiYgaGFzTWFwID8gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihNYXAucHJvdG90eXBlLCBcInNpemVcIikgOiBudWxsO1xuICAgIHZhciBtYXBTaXplID0gaGFzTWFwICYmIG1hcFNpemVEZXNjcmlwdG9yICYmIHR5cGVvZiBtYXBTaXplRGVzY3JpcHRvci5nZXQgPT09IFwiZnVuY3Rpb25cIiA/IG1hcFNpemVEZXNjcmlwdG9yLmdldCA6IG51bGw7XG4gICAgdmFyIG1hcEZvckVhY2ggPSBoYXNNYXAgJiYgTWFwLnByb3RvdHlwZS5mb3JFYWNoO1xuICAgIHZhciBoYXNTZXQgPSB0eXBlb2YgU2V0ID09PSBcImZ1bmN0aW9uXCIgJiYgU2V0LnByb3RvdHlwZTtcbiAgICB2YXIgc2V0U2l6ZURlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yICYmIGhhc1NldCA/IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoU2V0LnByb3RvdHlwZSwgXCJzaXplXCIpIDogbnVsbDtcbiAgICB2YXIgc2V0U2l6ZSA9IGhhc1NldCAmJiBzZXRTaXplRGVzY3JpcHRvciAmJiB0eXBlb2Ygc2V0U2l6ZURlc2NyaXB0b3IuZ2V0ID09PSBcImZ1bmN0aW9uXCIgPyBzZXRTaXplRGVzY3JpcHRvci5nZXQgOiBudWxsO1xuICAgIHZhciBzZXRGb3JFYWNoID0gaGFzU2V0ICYmIFNldC5wcm90b3R5cGUuZm9yRWFjaDtcbiAgICB2YXIgaGFzV2Vha01hcCA9IHR5cGVvZiBXZWFrTWFwID09PSBcImZ1bmN0aW9uXCIgJiYgV2Vha01hcC5wcm90b3R5cGU7XG4gICAgdmFyIHdlYWtNYXBIYXMgPSBoYXNXZWFrTWFwID8gV2Vha01hcC5wcm90b3R5cGUuaGFzIDogbnVsbDtcbiAgICB2YXIgaGFzV2Vha1NldCA9IHR5cGVvZiBXZWFrU2V0ID09PSBcImZ1bmN0aW9uXCIgJiYgV2Vha1NldC5wcm90b3R5cGU7XG4gICAgdmFyIHdlYWtTZXRIYXMgPSBoYXNXZWFrU2V0ID8gV2Vha1NldC5wcm90b3R5cGUuaGFzIDogbnVsbDtcbiAgICB2YXIgaGFzV2Vha1JlZiA9IHR5cGVvZiBXZWFrUmVmID09PSBcImZ1bmN0aW9uXCIgJiYgV2Vha1JlZi5wcm90b3R5cGU7XG4gICAgdmFyIHdlYWtSZWZEZXJlZiA9IGhhc1dlYWtSZWYgPyBXZWFrUmVmLnByb3RvdHlwZS5kZXJlZiA6IG51bGw7XG4gICAgdmFyIGJvb2xlYW5WYWx1ZU9mID0gQm9vbGVhbi5wcm90b3R5cGUudmFsdWVPZjtcbiAgICB2YXIgb2JqZWN0VG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuICAgIHZhciBmdW5jdGlvblRvU3RyaW5nID0gRnVuY3Rpb24ucHJvdG90eXBlLnRvU3RyaW5nO1xuICAgIHZhciAkbWF0Y2ggPSBTdHJpbmcucHJvdG90eXBlLm1hdGNoO1xuICAgIHZhciAkc2xpY2UgPSBTdHJpbmcucHJvdG90eXBlLnNsaWNlO1xuICAgIHZhciAkcmVwbGFjZSA9IFN0cmluZy5wcm90b3R5cGUucmVwbGFjZTtcbiAgICB2YXIgJHRvVXBwZXJDYXNlID0gU3RyaW5nLnByb3RvdHlwZS50b1VwcGVyQ2FzZTtcbiAgICB2YXIgJHRvTG93ZXJDYXNlID0gU3RyaW5nLnByb3RvdHlwZS50b0xvd2VyQ2FzZTtcbiAgICB2YXIgJHRlc3QgPSBSZWdFeHAucHJvdG90eXBlLnRlc3Q7XG4gICAgdmFyICRjb25jYXQgPSBBcnJheS5wcm90b3R5cGUuY29uY2F0O1xuICAgIHZhciAkam9pbiA9IEFycmF5LnByb3RvdHlwZS5qb2luO1xuICAgIHZhciAkYXJyU2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG4gICAgdmFyICRmbG9vciA9IE1hdGguZmxvb3I7XG4gICAgdmFyIGJpZ0ludFZhbHVlT2YgPSB0eXBlb2YgQmlnSW50ID09PSBcImZ1bmN0aW9uXCIgPyBCaWdJbnQucHJvdG90eXBlLnZhbHVlT2YgOiBudWxsO1xuICAgIHZhciBnT1BTID0gT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scztcbiAgICB2YXIgc3ltVG9TdHJpbmcgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIiA/IFN5bWJvbC5wcm90b3R5cGUudG9TdHJpbmcgOiBudWxsO1xuICAgIHZhciBoYXNTaGFtbWVkU3ltYm9scyA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgU3ltYm9sLml0ZXJhdG9yID09PSBcIm9iamVjdFwiO1xuICAgIHZhciB0b1N0cmluZ1RhZyA9IHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBTeW1ib2wudG9TdHJpbmdUYWcgJiYgKHR5cGVvZiBTeW1ib2wudG9TdHJpbmdUYWcgPT09IGhhc1NoYW1tZWRTeW1ib2xzID8gXCJvYmplY3RcIiA6IFwic3ltYm9sXCIpID8gU3ltYm9sLnRvU3RyaW5nVGFnIDogbnVsbDtcbiAgICB2YXIgaXNFbnVtZXJhYmxlID0gT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcbiAgICB2YXIgZ1BPID0gKHR5cGVvZiBSZWZsZWN0ID09PSBcImZ1bmN0aW9uXCIgPyBSZWZsZWN0LmdldFByb3RvdHlwZU9mIDogT2JqZWN0LmdldFByb3RvdHlwZU9mKSB8fCAoW10uX19wcm90b19fID09PSBBcnJheS5wcm90b3R5cGUgPyBmdW5jdGlvbihPKSB7XG4gICAgICByZXR1cm4gTy5fX3Byb3RvX187XG4gICAgfSA6IG51bGwpO1xuICAgIGZ1bmN0aW9uIGFkZE51bWVyaWNTZXBhcmF0b3IobnVtLCBzdHIpIHtcbiAgICAgIGlmIChudW0gPT09IEluZmluaXR5IHx8IG51bSA9PT0gLUluZmluaXR5IHx8IG51bSAhPT0gbnVtIHx8IG51bSAmJiBudW0gPiAtMWUzICYmIG51bSA8IDFlMyB8fCAkdGVzdC5jYWxsKC9lLywgc3RyKSkge1xuICAgICAgICByZXR1cm4gc3RyO1xuICAgICAgfVxuICAgICAgdmFyIHNlcFJlZ2V4ID0gL1swLTldKD89KD86WzAtOV17M30pKyg/IVswLTldKSkvZztcbiAgICAgIGlmICh0eXBlb2YgbnVtID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHZhciBpbnQgPSBudW0gPCAwID8gLSRmbG9vcigtbnVtKSA6ICRmbG9vcihudW0pO1xuICAgICAgICBpZiAoaW50ICE9PSBudW0pIHtcbiAgICAgICAgICB2YXIgaW50U3RyID0gU3RyaW5nKGludCk7XG4gICAgICAgICAgdmFyIGRlYyA9ICRzbGljZS5jYWxsKHN0ciwgaW50U3RyLmxlbmd0aCArIDEpO1xuICAgICAgICAgIHJldHVybiAkcmVwbGFjZS5jYWxsKGludFN0ciwgc2VwUmVnZXgsIFwiJCZfXCIpICsgXCIuXCIgKyAkcmVwbGFjZS5jYWxsKCRyZXBsYWNlLmNhbGwoZGVjLCAvKFswLTldezN9KS9nLCBcIiQmX1wiKSwgL18kLywgXCJcIik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiAkcmVwbGFjZS5jYWxsKHN0ciwgc2VwUmVnZXgsIFwiJCZfXCIpO1xuICAgIH1cbiAgICB2YXIgdXRpbEluc3BlY3QgPSByZXF1aXJlX3V0aWxfaW5zcGVjdCgpO1xuICAgIHZhciBpbnNwZWN0Q3VzdG9tID0gdXRpbEluc3BlY3QuY3VzdG9tO1xuICAgIHZhciBpbnNwZWN0U3ltYm9sID0gaXNTeW1ib2woaW5zcGVjdEN1c3RvbSkgPyBpbnNwZWN0Q3VzdG9tIDogbnVsbDtcbiAgICB2YXIgcXVvdGVzID0ge1xuICAgICAgX19wcm90b19fOiBudWxsLFxuICAgICAgXCJkb3VibGVcIjogJ1wiJyxcbiAgICAgIHNpbmdsZTogXCInXCJcbiAgICB9O1xuICAgIHZhciBxdW90ZVJFcyA9IHtcbiAgICAgIF9fcHJvdG9fXzogbnVsbCxcbiAgICAgIFwiZG91YmxlXCI6IC8oW1wiXFxcXF0pL2csXG4gICAgICBzaW5nbGU6IC8oWydcXFxcXSkvZ1xuICAgIH07XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbnNwZWN0XyhvYmosIG9wdGlvbnMsIGRlcHRoLCBzZWVuKSB7XG4gICAgICB2YXIgb3B0cyA9IG9wdGlvbnMgfHwge307XG4gICAgICBpZiAoaGFzKG9wdHMsIFwicXVvdGVTdHlsZVwiKSAmJiAhaGFzKHF1b3Rlcywgb3B0cy5xdW90ZVN0eWxlKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb24gXCJxdW90ZVN0eWxlXCIgbXVzdCBiZSBcInNpbmdsZVwiIG9yIFwiZG91YmxlXCInKTtcbiAgICAgIH1cbiAgICAgIGlmIChoYXMob3B0cywgXCJtYXhTdHJpbmdMZW5ndGhcIikgJiYgKHR5cGVvZiBvcHRzLm1heFN0cmluZ0xlbmd0aCA9PT0gXCJudW1iZXJcIiA/IG9wdHMubWF4U3RyaW5nTGVuZ3RoIDwgMCAmJiBvcHRzLm1heFN0cmluZ0xlbmd0aCAhPT0gSW5maW5pdHkgOiBvcHRzLm1heFN0cmluZ0xlbmd0aCAhPT0gbnVsbCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwibWF4U3RyaW5nTGVuZ3RoXCIsIGlmIHByb3ZpZGVkLCBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlciwgSW5maW5pdHksIG9yIGBudWxsYCcpO1xuICAgICAgfVxuICAgICAgdmFyIGN1c3RvbUluc3BlY3QgPSBoYXMob3B0cywgXCJjdXN0b21JbnNwZWN0XCIpID8gb3B0cy5jdXN0b21JbnNwZWN0IDogdHJ1ZTtcbiAgICAgIGlmICh0eXBlb2YgY3VzdG9tSW5zcGVjdCAhPT0gXCJib29sZWFuXCIgJiYgY3VzdG9tSW5zcGVjdCAhPT0gXCJzeW1ib2xcIikge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwib3B0aW9uIFxcXCJjdXN0b21JbnNwZWN0XFxcIiwgaWYgcHJvdmlkZWQsIG11c3QgYmUgYHRydWVgLCBgZmFsc2VgLCBvciBgJ3N5bWJvbCdgXCIpO1xuICAgICAgfVxuICAgICAgaWYgKGhhcyhvcHRzLCBcImluZGVudFwiKSAmJiBvcHRzLmluZGVudCAhPT0gbnVsbCAmJiBvcHRzLmluZGVudCAhPT0gXCJcdFwiICYmICEocGFyc2VJbnQob3B0cy5pbmRlbnQsIDEwKSA9PT0gb3B0cy5pbmRlbnQgJiYgb3B0cy5pbmRlbnQgPiAwKSkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdvcHRpb24gXCJpbmRlbnRcIiBtdXN0IGJlIFwiXFxcXHRcIiwgYW4gaW50ZWdlciA+IDAsIG9yIGBudWxsYCcpO1xuICAgICAgfVxuICAgICAgaWYgKGhhcyhvcHRzLCBcIm51bWVyaWNTZXBhcmF0b3JcIikgJiYgdHlwZW9mIG9wdHMubnVtZXJpY1NlcGFyYXRvciAhPT0gXCJib29sZWFuXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignb3B0aW9uIFwibnVtZXJpY1NlcGFyYXRvclwiLCBpZiBwcm92aWRlZCwgbXVzdCBiZSBgdHJ1ZWAgb3IgYGZhbHNlYCcpO1xuICAgICAgfVxuICAgICAgdmFyIG51bWVyaWNTZXBhcmF0b3IgPSBvcHRzLm51bWVyaWNTZXBhcmF0b3I7XG4gICAgICBpZiAodHlwZW9mIG9iaiA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICByZXR1cm4gXCJ1bmRlZmluZWRcIjtcbiAgICAgIH1cbiAgICAgIGlmIChvYmogPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIFwibnVsbFwiO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBvYmogPT09IFwiYm9vbGVhblwiKSB7XG4gICAgICAgIHJldHVybiBvYmogPyBcInRydWVcIiA6IFwiZmFsc2VcIjtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2Ygb2JqID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHJldHVybiBpbnNwZWN0U3RyaW5nKG9iaiwgb3B0cyk7XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIG9iaiA9PT0gXCJudW1iZXJcIikge1xuICAgICAgICBpZiAob2JqID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIEluZmluaXR5IC8gb2JqID4gMCA/IFwiMFwiIDogXCItMFwiO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzdHIgPSBTdHJpbmcob2JqKTtcbiAgICAgICAgcmV0dXJuIG51bWVyaWNTZXBhcmF0b3IgPyBhZGROdW1lcmljU2VwYXJhdG9yKG9iaiwgc3RyKSA6IHN0cjtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2Ygb2JqID09PSBcImJpZ2ludFwiKSB7XG4gICAgICAgIHZhciBiaWdJbnRTdHIgPSBTdHJpbmcob2JqKSArIFwiblwiO1xuICAgICAgICByZXR1cm4gbnVtZXJpY1NlcGFyYXRvciA/IGFkZE51bWVyaWNTZXBhcmF0b3Iob2JqLCBiaWdJbnRTdHIpIDogYmlnSW50U3RyO1xuICAgICAgfVxuICAgICAgdmFyIG1heERlcHRoID0gdHlwZW9mIG9wdHMuZGVwdGggPT09IFwidW5kZWZpbmVkXCIgPyA1IDogb3B0cy5kZXB0aDtcbiAgICAgIGlmICh0eXBlb2YgZGVwdGggPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgZGVwdGggPSAwO1xuICAgICAgfVxuICAgICAgaWYgKGRlcHRoID49IG1heERlcHRoICYmIG1heERlcHRoID4gMCAmJiB0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIHJldHVybiBpc0FycmF5KG9iaikgPyBcIltBcnJheV1cIiA6IFwiW09iamVjdF1cIjtcbiAgICAgIH1cbiAgICAgIHZhciBpbmRlbnQgPSBnZXRJbmRlbnQob3B0cywgZGVwdGgpO1xuICAgICAgaWYgKHR5cGVvZiBzZWVuID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIHNlZW4gPSBbXTtcbiAgICAgIH0gZWxzZSBpZiAoaW5kZXhPZihzZWVuLCBvYmopID49IDApIHtcbiAgICAgICAgcmV0dXJuIFwiW0NpcmN1bGFyXVwiO1xuICAgICAgfVxuICAgICAgZnVuY3Rpb24gaW5zcGVjdDModmFsdWUsIGZyb20sIG5vSW5kZW50KSB7XG4gICAgICAgIGlmIChmcm9tKSB7XG4gICAgICAgICAgc2VlbiA9ICRhcnJTbGljZS5jYWxsKHNlZW4pO1xuICAgICAgICAgIHNlZW4ucHVzaChmcm9tKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobm9JbmRlbnQpIHtcbiAgICAgICAgICB2YXIgbmV3T3B0cyA9IHtcbiAgICAgICAgICAgIGRlcHRoOiBvcHRzLmRlcHRoXG4gICAgICAgICAgfTtcbiAgICAgICAgICBpZiAoaGFzKG9wdHMsIFwicXVvdGVTdHlsZVwiKSkge1xuICAgICAgICAgICAgbmV3T3B0cy5xdW90ZVN0eWxlID0gb3B0cy5xdW90ZVN0eWxlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gaW5zcGVjdF8odmFsdWUsIG5ld09wdHMsIGRlcHRoICsgMSwgc2Vlbik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGluc3BlY3RfKHZhbHVlLCBvcHRzLCBkZXB0aCArIDEsIHNlZW4pO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBvYmogPT09IFwiZnVuY3Rpb25cIiAmJiAhaXNSZWdFeHAob2JqKSkge1xuICAgICAgICB2YXIgbmFtZSA9IG5hbWVPZihvYmopO1xuICAgICAgICB2YXIga2V5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0Myk7XG4gICAgICAgIHJldHVybiBcIltGdW5jdGlvblwiICsgKG5hbWUgPyBcIjogXCIgKyBuYW1lIDogXCIgKGFub255bW91cylcIikgKyBcIl1cIiArIChrZXlzLmxlbmd0aCA+IDAgPyBcIiB7IFwiICsgJGpvaW4uY2FsbChrZXlzLCBcIiwgXCIpICsgXCIgfVwiIDogXCJcIik7XG4gICAgICB9XG4gICAgICBpZiAoaXNTeW1ib2wob2JqKSkge1xuICAgICAgICB2YXIgc3ltU3RyaW5nID0gaGFzU2hhbW1lZFN5bWJvbHMgPyAkcmVwbGFjZS5jYWxsKFN0cmluZyhvYmopLCAvXihTeW1ib2xcXCguKlxcKSlfW14pXSokLywgXCIkMVwiKSA6IHN5bVRvU3RyaW5nLmNhbGwob2JqKTtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBvYmogPT09IFwib2JqZWN0XCIgJiYgIWhhc1NoYW1tZWRTeW1ib2xzID8gbWFya0JveGVkKHN5bVN0cmluZykgOiBzeW1TdHJpbmc7XG4gICAgICB9XG4gICAgICBpZiAoaXNFbGVtZW50KG9iaikpIHtcbiAgICAgICAgdmFyIHMgPSBcIjxcIiArICR0b0xvd2VyQ2FzZS5jYWxsKFN0cmluZyhvYmoubm9kZU5hbWUpKTtcbiAgICAgICAgdmFyIGF0dHJzID0gb2JqLmF0dHJpYnV0ZXMgfHwgW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXR0cnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICBzICs9IFwiIFwiICsgYXR0cnNbaV0ubmFtZSArIFwiPVwiICsgd3JhcFF1b3RlcyhxdW90ZShhdHRyc1tpXS52YWx1ZSksIFwiZG91YmxlXCIsIG9wdHMpO1xuICAgICAgICB9XG4gICAgICAgIHMgKz0gXCI+XCI7XG4gICAgICAgIGlmIChvYmouY2hpbGROb2RlcyAmJiBvYmouY2hpbGROb2Rlcy5sZW5ndGgpIHtcbiAgICAgICAgICBzICs9IFwiLi4uXCI7XG4gICAgICAgIH1cbiAgICAgICAgcyArPSBcIjwvXCIgKyAkdG9Mb3dlckNhc2UuY2FsbChTdHJpbmcob2JqLm5vZGVOYW1lKSkgKyBcIj5cIjtcbiAgICAgICAgcmV0dXJuIHM7XG4gICAgICB9XG4gICAgICBpZiAoaXNBcnJheShvYmopKSB7XG4gICAgICAgIGlmIChvYmoubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIFwiW11cIjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgeHMgPSBhcnJPYmpLZXlzKG9iaiwgaW5zcGVjdDMpO1xuICAgICAgICBpZiAoaW5kZW50ICYmICFzaW5nbGVMaW5lVmFsdWVzKHhzKSkge1xuICAgICAgICAgIHJldHVybiBcIltcIiArIGluZGVudGVkSm9pbih4cywgaW5kZW50KSArIFwiXVwiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBcIlsgXCIgKyAkam9pbi5jYWxsKHhzLCBcIiwgXCIpICsgXCIgXVwiO1xuICAgICAgfVxuICAgICAgaWYgKGlzRXJyb3Iob2JqKSkge1xuICAgICAgICB2YXIgcGFydHMgPSBhcnJPYmpLZXlzKG9iaiwgaW5zcGVjdDMpO1xuICAgICAgICBpZiAoIShcImNhdXNlXCIgaW4gRXJyb3IucHJvdG90eXBlKSAmJiBcImNhdXNlXCIgaW4gb2JqICYmICFpc0VudW1lcmFibGUuY2FsbChvYmosIFwiY2F1c2VcIikpIHtcbiAgICAgICAgICByZXR1cm4gXCJ7IFtcIiArIFN0cmluZyhvYmopICsgXCJdIFwiICsgJGpvaW4uY2FsbCgkY29uY2F0LmNhbGwoXCJbY2F1c2VdOiBcIiArIGluc3BlY3QzKG9iai5jYXVzZSksIHBhcnRzKSwgXCIsIFwiKSArIFwiIH1cIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFydHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIFwiW1wiICsgU3RyaW5nKG9iaikgKyBcIl1cIjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gXCJ7IFtcIiArIFN0cmluZyhvYmopICsgXCJdIFwiICsgJGpvaW4uY2FsbChwYXJ0cywgXCIsIFwiKSArIFwiIH1cIjtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiICYmIGN1c3RvbUluc3BlY3QpIHtcbiAgICAgICAgaWYgKGluc3BlY3RTeW1ib2wgJiYgdHlwZW9mIG9ialtpbnNwZWN0U3ltYm9sXSA9PT0gXCJmdW5jdGlvblwiICYmIHV0aWxJbnNwZWN0KSB7XG4gICAgICAgICAgcmV0dXJuIHV0aWxJbnNwZWN0KG9iaiwgeyBkZXB0aDogbWF4RGVwdGggLSBkZXB0aCB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChjdXN0b21JbnNwZWN0ICE9PSBcInN5bWJvbFwiICYmIHR5cGVvZiBvYmouaW5zcGVjdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgcmV0dXJuIG9iai5pbnNwZWN0KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChpc01hcChvYmopKSB7XG4gICAgICAgIHZhciBtYXBQYXJ0cyA9IFtdO1xuICAgICAgICBpZiAobWFwRm9yRWFjaCkge1xuICAgICAgICAgIG1hcEZvckVhY2guY2FsbChvYmosIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICAgICAgICAgIG1hcFBhcnRzLnB1c2goaW5zcGVjdDMoa2V5LCBvYmosIHRydWUpICsgXCIgPT4gXCIgKyBpbnNwZWN0Myh2YWx1ZSwgb2JqKSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZihcIk1hcFwiLCBtYXBTaXplLmNhbGwob2JqKSwgbWFwUGFydHMsIGluZGVudCk7XG4gICAgICB9XG4gICAgICBpZiAoaXNTZXQob2JqKSkge1xuICAgICAgICB2YXIgc2V0UGFydHMgPSBbXTtcbiAgICAgICAgaWYgKHNldEZvckVhY2gpIHtcbiAgICAgICAgICBzZXRGb3JFYWNoLmNhbGwob2JqLCBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAgICAgc2V0UGFydHMucHVzaChpbnNwZWN0Myh2YWx1ZSwgb2JqKSk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNvbGxlY3Rpb25PZihcIlNldFwiLCBzZXRTaXplLmNhbGwob2JqKSwgc2V0UGFydHMsIGluZGVudCk7XG4gICAgICB9XG4gICAgICBpZiAoaXNXZWFrTWFwKG9iaikpIHtcbiAgICAgICAgcmV0dXJuIHdlYWtDb2xsZWN0aW9uT2YoXCJXZWFrTWFwXCIpO1xuICAgICAgfVxuICAgICAgaWYgKGlzV2Vha1NldChvYmopKSB7XG4gICAgICAgIHJldHVybiB3ZWFrQ29sbGVjdGlvbk9mKFwiV2Vha1NldFwiKTtcbiAgICAgIH1cbiAgICAgIGlmIChpc1dlYWtSZWYob2JqKSkge1xuICAgICAgICByZXR1cm4gd2Vha0NvbGxlY3Rpb25PZihcIldlYWtSZWZcIik7XG4gICAgICB9XG4gICAgICBpZiAoaXNOdW1iZXIob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGluc3BlY3QzKE51bWJlcihvYmopKSk7XG4gICAgICB9XG4gICAgICBpZiAoaXNCaWdJbnQob2JqKSkge1xuICAgICAgICByZXR1cm4gbWFya0JveGVkKGluc3BlY3QzKGJpZ0ludFZhbHVlT2YuY2FsbChvYmopKSk7XG4gICAgICB9XG4gICAgICBpZiAoaXNCb29sZWFuKG9iaikpIHtcbiAgICAgICAgcmV0dXJuIG1hcmtCb3hlZChib29sZWFuVmFsdWVPZi5jYWxsKG9iaikpO1xuICAgICAgfVxuICAgICAgaWYgKGlzU3RyaW5nKG9iaikpIHtcbiAgICAgICAgcmV0dXJuIG1hcmtCb3hlZChpbnNwZWN0MyhTdHJpbmcob2JqKSkpO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiYgb2JqID09PSB3aW5kb3cpIHtcbiAgICAgICAgcmV0dXJuIFwieyBbb2JqZWN0IFdpbmRvd10gfVwiO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBnbG9iYWxUaGlzICE9PSBcInVuZGVmaW5lZFwiICYmIG9iaiA9PT0gZ2xvYmFsVGhpcyB8fCB0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiICYmIG9iaiA9PT0gZ2xvYmFsKSB7XG4gICAgICAgIHJldHVybiBcInsgW29iamVjdCBnbG9iYWxUaGlzXSB9XCI7XG4gICAgICB9XG4gICAgICBpZiAoIWlzRGF0ZShvYmopICYmICFpc1JlZ0V4cChvYmopKSB7XG4gICAgICAgIHZhciB5cyA9IGFyck9iaktleXMob2JqLCBpbnNwZWN0Myk7XG4gICAgICAgIHZhciBpc1BsYWluT2JqZWN0ID0gZ1BPID8gZ1BPKG9iaikgPT09IE9iamVjdC5wcm90b3R5cGUgOiBvYmogaW5zdGFuY2VvZiBPYmplY3QgfHwgb2JqLmNvbnN0cnVjdG9yID09PSBPYmplY3Q7XG4gICAgICAgIHZhciBwcm90b1RhZyA9IG9iaiBpbnN0YW5jZW9mIE9iamVjdCA/IFwiXCIgOiBcIm51bGwgcHJvdG90eXBlXCI7XG4gICAgICAgIHZhciBzdHJpbmdUYWcgPSAhaXNQbGFpbk9iamVjdCAmJiB0b1N0cmluZ1RhZyAmJiBPYmplY3Qob2JqKSA9PT0gb2JqICYmIHRvU3RyaW5nVGFnIGluIG9iaiA/ICRzbGljZS5jYWxsKHRvU3RyKG9iaiksIDgsIC0xKSA6IHByb3RvVGFnID8gXCJPYmplY3RcIiA6IFwiXCI7XG4gICAgICAgIHZhciBjb25zdHJ1Y3RvclRhZyA9IGlzUGxhaW5PYmplY3QgfHwgdHlwZW9mIG9iai5jb25zdHJ1Y3RvciAhPT0gXCJmdW5jdGlvblwiID8gXCJcIiA6IG9iai5jb25zdHJ1Y3Rvci5uYW1lID8gb2JqLmNvbnN0cnVjdG9yLm5hbWUgKyBcIiBcIiA6IFwiXCI7XG4gICAgICAgIHZhciB0YWcgPSBjb25zdHJ1Y3RvclRhZyArIChzdHJpbmdUYWcgfHwgcHJvdG9UYWcgPyBcIltcIiArICRqb2luLmNhbGwoJGNvbmNhdC5jYWxsKFtdLCBzdHJpbmdUYWcgfHwgW10sIHByb3RvVGFnIHx8IFtdKSwgXCI6IFwiKSArIFwiXSBcIiA6IFwiXCIpO1xuICAgICAgICBpZiAoeXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIHRhZyArIFwie31cIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaW5kZW50KSB7XG4gICAgICAgICAgcmV0dXJuIHRhZyArIFwie1wiICsgaW5kZW50ZWRKb2luKHlzLCBpbmRlbnQpICsgXCJ9XCI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRhZyArIFwieyBcIiArICRqb2luLmNhbGwoeXMsIFwiLCBcIikgKyBcIiB9XCI7XG4gICAgICB9XG4gICAgICByZXR1cm4gU3RyaW5nKG9iaik7XG4gICAgfTtcbiAgICBmdW5jdGlvbiB3cmFwUXVvdGVzKHMsIGRlZmF1bHRTdHlsZSwgb3B0cykge1xuICAgICAgdmFyIHN0eWxlID0gb3B0cy5xdW90ZVN0eWxlIHx8IGRlZmF1bHRTdHlsZTtcbiAgICAgIHZhciBxdW90ZUNoYXIgPSBxdW90ZXNbc3R5bGVdO1xuICAgICAgcmV0dXJuIHF1b3RlQ2hhciArIHMgKyBxdW90ZUNoYXI7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHF1b3RlKHMpIHtcbiAgICAgIHJldHVybiAkcmVwbGFjZS5jYWxsKFN0cmluZyhzKSwgL1wiL2csIFwiJnF1b3Q7XCIpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBjYW5UcnVzdFRvU3RyaW5nKG9iaikge1xuICAgICAgcmV0dXJuICF0b1N0cmluZ1RhZyB8fCAhKHR5cGVvZiBvYmogPT09IFwib2JqZWN0XCIgJiYgKHRvU3RyaW5nVGFnIGluIG9iaiB8fCB0eXBlb2Ygb2JqW3RvU3RyaW5nVGFnXSAhPT0gXCJ1bmRlZmluZWRcIikpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBpc0FycmF5KG9iaikge1xuICAgICAgcmV0dXJuIHRvU3RyKG9iaikgPT09IFwiW29iamVjdCBBcnJheV1cIiAmJiBjYW5UcnVzdFRvU3RyaW5nKG9iaik7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGlzRGF0ZShvYmopIHtcbiAgICAgIHJldHVybiB0b1N0cihvYmopID09PSBcIltvYmplY3QgRGF0ZV1cIiAmJiBjYW5UcnVzdFRvU3RyaW5nKG9iaik7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGlzUmVnRXhwKG9iaikge1xuICAgICAgcmV0dXJuIHRvU3RyKG9iaikgPT09IFwiW29iamVjdCBSZWdFeHBdXCIgJiYgY2FuVHJ1c3RUb1N0cmluZyhvYmopO1xuICAgIH1cbiAgICBmdW5jdGlvbiBpc0Vycm9yKG9iaikge1xuICAgICAgcmV0dXJuIHRvU3RyKG9iaikgPT09IFwiW29iamVjdCBFcnJvcl1cIiAmJiBjYW5UcnVzdFRvU3RyaW5nKG9iaik7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGlzU3RyaW5nKG9iaikge1xuICAgICAgcmV0dXJuIHRvU3RyKG9iaikgPT09IFwiW29iamVjdCBTdHJpbmddXCIgJiYgY2FuVHJ1c3RUb1N0cmluZyhvYmopO1xuICAgIH1cbiAgICBmdW5jdGlvbiBpc051bWJlcihvYmopIHtcbiAgICAgIHJldHVybiB0b1N0cihvYmopID09PSBcIltvYmplY3QgTnVtYmVyXVwiICYmIGNhblRydXN0VG9TdHJpbmcob2JqKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gaXNCb29sZWFuKG9iaikge1xuICAgICAgcmV0dXJuIHRvU3RyKG9iaikgPT09IFwiW29iamVjdCBCb29sZWFuXVwiICYmIGNhblRydXN0VG9TdHJpbmcob2JqKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gaXNTeW1ib2wob2JqKSB7XG4gICAgICBpZiAoaGFzU2hhbW1lZFN5bWJvbHMpIHtcbiAgICAgICAgcmV0dXJuIG9iaiAmJiB0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiICYmIG9iaiBpbnN0YW5jZW9mIFN5bWJvbDtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2Ygb2JqID09PSBcInN5bWJvbFwiKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKCFvYmogfHwgdHlwZW9mIG9iaiAhPT0gXCJvYmplY3RcIiB8fCAhc3ltVG9TdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgc3ltVG9TdHJpbmcuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gaXNCaWdJbnQob2JqKSB7XG4gICAgICBpZiAoIW9iaiB8fCB0eXBlb2Ygb2JqICE9PSBcIm9iamVjdFwiIHx8ICFiaWdJbnRWYWx1ZU9mKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIGJpZ0ludFZhbHVlT2YuY2FsbChvYmopO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdmFyIGhhc093bjIgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5IHx8IGZ1bmN0aW9uKGtleSkge1xuICAgICAgcmV0dXJuIGtleSBpbiB0aGlzO1xuICAgIH07XG4gICAgZnVuY3Rpb24gaGFzKG9iaiwga2V5KSB7XG4gICAgICByZXR1cm4gaGFzT3duMi5jYWxsKG9iaiwga2V5KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gdG9TdHIob2JqKSB7XG4gICAgICByZXR1cm4gb2JqZWN0VG9TdHJpbmcuY2FsbChvYmopO1xuICAgIH1cbiAgICBmdW5jdGlvbiBuYW1lT2YoZikge1xuICAgICAgaWYgKGYubmFtZSkge1xuICAgICAgICByZXR1cm4gZi5uYW1lO1xuICAgICAgfVxuICAgICAgdmFyIG0gPSAkbWF0Y2guY2FsbChmdW5jdGlvblRvU3RyaW5nLmNhbGwoZiksIC9eZnVuY3Rpb25cXHMqKFtcXHckXSspLyk7XG4gICAgICBpZiAobSkge1xuICAgICAgICByZXR1cm4gbVsxXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBmdW5jdGlvbiBpbmRleE9mKHhzLCB4KSB7XG4gICAgICBpZiAoeHMuaW5kZXhPZikge1xuICAgICAgICByZXR1cm4geHMuaW5kZXhPZih4KTtcbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGkgPSAwLCBsID0geHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIGlmICh4c1tpXSA9PT0geCkge1xuICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGlzTWFwKHgpIHtcbiAgICAgIGlmICghbWFwU2l6ZSB8fCAheCB8fCB0eXBlb2YgeCAhPT0gXCJvYmplY3RcIikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICBtYXBTaXplLmNhbGwoeCk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgc2V0U2l6ZS5jYWxsKHgpO1xuICAgICAgICB9IGNhdGNoIChzKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBNYXA7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGlzV2Vha01hcCh4KSB7XG4gICAgICBpZiAoIXdlYWtNYXBIYXMgfHwgIXggfHwgdHlwZW9mIHggIT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgd2Vha01hcEhhcy5jYWxsKHgsIHdlYWtNYXBIYXMpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHdlYWtTZXRIYXMuY2FsbCh4LCB3ZWFrU2V0SGFzKTtcbiAgICAgICAgfSBjYXRjaCAocykge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB4IGluc3RhbmNlb2YgV2Vha01hcDtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gaXNXZWFrUmVmKHgpIHtcbiAgICAgIGlmICghd2Vha1JlZkRlcmVmIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIHdlYWtSZWZEZXJlZi5jYWxsKHgpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gaXNTZXQoeCkge1xuICAgICAgaWYgKCFzZXRTaXplIHx8ICF4IHx8IHR5cGVvZiB4ICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIHNldFNpemUuY2FsbCh4KTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBtYXBTaXplLmNhbGwoeCk7XG4gICAgICAgIH0gY2F0Y2ggKG0pIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geCBpbnN0YW5jZW9mIFNldDtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gaXNXZWFrU2V0KHgpIHtcbiAgICAgIGlmICghd2Vha1NldEhhcyB8fCAheCB8fCB0eXBlb2YgeCAhPT0gXCJvYmplY3RcIikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICB3ZWFrU2V0SGFzLmNhbGwoeCwgd2Vha1NldEhhcyk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgd2Vha01hcEhhcy5jYWxsKHgsIHdlYWtNYXBIYXMpO1xuICAgICAgICB9IGNhdGNoIChzKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHggaW5zdGFuY2VvZiBXZWFrU2V0O1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBmdW5jdGlvbiBpc0VsZW1lbnQoeCkge1xuICAgICAgaWYgKCF4IHx8IHR5cGVvZiB4ICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgSFRNTEVsZW1lbnQgIT09IFwidW5kZWZpbmVkXCIgJiYgeCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHR5cGVvZiB4Lm5vZGVOYW1lID09PSBcInN0cmluZ1wiICYmIHR5cGVvZiB4LmdldEF0dHJpYnV0ZSA9PT0gXCJmdW5jdGlvblwiO1xuICAgIH1cbiAgICBmdW5jdGlvbiBpbnNwZWN0U3RyaW5nKHN0ciwgb3B0cykge1xuICAgICAgaWYgKHN0ci5sZW5ndGggPiBvcHRzLm1heFN0cmluZ0xlbmd0aCkge1xuICAgICAgICB2YXIgcmVtYWluaW5nID0gc3RyLmxlbmd0aCAtIG9wdHMubWF4U3RyaW5nTGVuZ3RoO1xuICAgICAgICB2YXIgdHJhaWxlciA9IFwiLi4uIFwiICsgcmVtYWluaW5nICsgXCIgbW9yZSBjaGFyYWN0ZXJcIiArIChyZW1haW5pbmcgPiAxID8gXCJzXCIgOiBcIlwiKTtcbiAgICAgICAgcmV0dXJuIGluc3BlY3RTdHJpbmcoJHNsaWNlLmNhbGwoc3RyLCAwLCBvcHRzLm1heFN0cmluZ0xlbmd0aCksIG9wdHMpICsgdHJhaWxlcjtcbiAgICAgIH1cbiAgICAgIHZhciBxdW90ZVJFID0gcXVvdGVSRXNbb3B0cy5xdW90ZVN0eWxlIHx8IFwic2luZ2xlXCJdO1xuICAgICAgcXVvdGVSRS5sYXN0SW5kZXggPSAwO1xuICAgICAgdmFyIHMgPSAkcmVwbGFjZS5jYWxsKCRyZXBsYWNlLmNhbGwoc3RyLCBxdW90ZVJFLCBcIlxcXFwkMVwiKSwgL1tcXHgwMC1cXHgxZl0vZywgbG93Ynl0ZSk7XG4gICAgICByZXR1cm4gd3JhcFF1b3RlcyhzLCBcInNpbmdsZVwiLCBvcHRzKTtcbiAgICB9XG4gICAgZnVuY3Rpb24gbG93Ynl0ZShjKSB7XG4gICAgICB2YXIgbiA9IGMuY2hhckNvZGVBdCgwKTtcbiAgICAgIHZhciB4ID0ge1xuICAgICAgICA4OiBcImJcIixcbiAgICAgICAgOTogXCJ0XCIsXG4gICAgICAgIDEwOiBcIm5cIixcbiAgICAgICAgMTI6IFwiZlwiLFxuICAgICAgICAxMzogXCJyXCJcbiAgICAgIH1bbl07XG4gICAgICBpZiAoeCkge1xuICAgICAgICByZXR1cm4gXCJcXFxcXCIgKyB4O1xuICAgICAgfVxuICAgICAgcmV0dXJuIFwiXFxcXHhcIiArIChuIDwgMTYgPyBcIjBcIiA6IFwiXCIpICsgJHRvVXBwZXJDYXNlLmNhbGwobi50b1N0cmluZygxNikpO1xuICAgIH1cbiAgICBmdW5jdGlvbiBtYXJrQm94ZWQoc3RyKSB7XG4gICAgICByZXR1cm4gXCJPYmplY3QoXCIgKyBzdHIgKyBcIilcIjtcbiAgICB9XG4gICAgZnVuY3Rpb24gd2Vha0NvbGxlY3Rpb25PZih0eXBlKSB7XG4gICAgICByZXR1cm4gdHlwZSArIFwiIHsgPyB9XCI7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGNvbGxlY3Rpb25PZih0eXBlLCBzaXplLCBlbnRyaWVzLCBpbmRlbnQpIHtcbiAgICAgIHZhciBqb2luZWRFbnRyaWVzID0gaW5kZW50ID8gaW5kZW50ZWRKb2luKGVudHJpZXMsIGluZGVudCkgOiAkam9pbi5jYWxsKGVudHJpZXMsIFwiLCBcIik7XG4gICAgICByZXR1cm4gdHlwZSArIFwiIChcIiArIHNpemUgKyBcIikge1wiICsgam9pbmVkRW50cmllcyArIFwifVwiO1xuICAgIH1cbiAgICBmdW5jdGlvbiBzaW5nbGVMaW5lVmFsdWVzKHhzKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmIChpbmRleE9mKHhzW2ldLCBcIlxcblwiKSA+PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgZnVuY3Rpb24gZ2V0SW5kZW50KG9wdHMsIGRlcHRoKSB7XG4gICAgICB2YXIgYmFzZUluZGVudDtcbiAgICAgIGlmIChvcHRzLmluZGVudCA9PT0gXCJcdFwiKSB7XG4gICAgICAgIGJhc2VJbmRlbnQgPSBcIlx0XCI7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBvcHRzLmluZGVudCA9PT0gXCJudW1iZXJcIiAmJiBvcHRzLmluZGVudCA+IDApIHtcbiAgICAgICAgYmFzZUluZGVudCA9ICRqb2luLmNhbGwoQXJyYXkob3B0cy5pbmRlbnQgKyAxKSwgXCIgXCIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICBiYXNlOiBiYXNlSW5kZW50LFxuICAgICAgICBwcmV2OiAkam9pbi5jYWxsKEFycmF5KGRlcHRoICsgMSksIGJhc2VJbmRlbnQpXG4gICAgICB9O1xuICAgIH1cbiAgICBmdW5jdGlvbiBpbmRlbnRlZEpvaW4oeHMsIGluZGVudCkge1xuICAgICAgaWYgKHhzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gXCJcIjtcbiAgICAgIH1cbiAgICAgIHZhciBsaW5lSm9pbmVyID0gXCJcXG5cIiArIGluZGVudC5wcmV2ICsgaW5kZW50LmJhc2U7XG4gICAgICByZXR1cm4gbGluZUpvaW5lciArICRqb2luLmNhbGwoeHMsIFwiLFwiICsgbGluZUpvaW5lcikgKyBcIlxcblwiICsgaW5kZW50LnByZXY7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGFyck9iaktleXMob2JqLCBpbnNwZWN0Mykge1xuICAgICAgdmFyIGlzQXJyID0gaXNBcnJheShvYmopO1xuICAgICAgdmFyIHhzID0gW107XG4gICAgICBpZiAoaXNBcnIpIHtcbiAgICAgICAgeHMubGVuZ3RoID0gb2JqLmxlbmd0aDtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvYmoubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICB4c1tpXSA9IGhhcyhvYmosIGkpID8gaW5zcGVjdDMob2JqW2ldLCBvYmopIDogXCJcIjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdmFyIHN5bXMgPSB0eXBlb2YgZ09QUyA9PT0gXCJmdW5jdGlvblwiID8gZ09QUyhvYmopIDogW107XG4gICAgICB2YXIgc3ltTWFwO1xuICAgICAgaWYgKGhhc1NoYW1tZWRTeW1ib2xzKSB7XG4gICAgICAgIHN5bU1hcCA9IHt9O1xuICAgICAgICBmb3IgKHZhciBrID0gMDsgayA8IHN5bXMubGVuZ3RoOyBrKyspIHtcbiAgICAgICAgICBzeW1NYXBbXCIkXCIgKyBzeW1zW2tdXSA9IHN5bXNba107XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgICAgaWYgKCFoYXMob2JqLCBrZXkpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzQXJyICYmIFN0cmluZyhOdW1iZXIoa2V5KSkgPT09IGtleSAmJiBrZXkgPCBvYmoubGVuZ3RoKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhhc1NoYW1tZWRTeW1ib2xzICYmIHN5bU1hcFtcIiRcIiArIGtleV0gaW5zdGFuY2VvZiBTeW1ib2wpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfSBlbHNlIGlmICgkdGVzdC5jYWxsKC9bXlxcdyRdLywga2V5KSkge1xuICAgICAgICAgIHhzLnB1c2goaW5zcGVjdDMoa2V5LCBvYmopICsgXCI6IFwiICsgaW5zcGVjdDMob2JqW2tleV0sIG9iaikpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHhzLnB1c2goa2V5ICsgXCI6IFwiICsgaW5zcGVjdDMob2JqW2tleV0sIG9iaikpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIGdPUFMgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IHN5bXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgICBpZiAoaXNFbnVtZXJhYmxlLmNhbGwob2JqLCBzeW1zW2pdKSkge1xuICAgICAgICAgICAgeHMucHVzaChcIltcIiArIGluc3BlY3QzKHN5bXNbal0pICsgXCJdOiBcIiArIGluc3BlY3QzKG9ialtzeW1zW2pdXSwgb2JqKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4geHM7XG4gICAgfVxuICB9XG59KTtcblxuLy8gc3JjL2xpYi90aW1lX2R1cmF0aW9uLnRzXG52YXIgVGltZUR1cmF0aW9uID0gY2xhc3MgX1RpbWVEdXJhdGlvbiB7XG4gIF9fdGltZV9kdXJhdGlvbl9taWNyb3NfXztcbiAgc3RhdGljIE1JQ1JPU19QRVJfTUlMTElTID0gMTAwMG47XG4gIC8qKlxuICAgKiBHZXQgdGhlIGFsZ2VicmFpYyB0eXBlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB7QGxpbmsgVGltZUR1cmF0aW9ufSB0eXBlLlxuICAgKiBAcmV0dXJucyBUaGUgYWxnZWJyYWljIHR5cGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIHR5cGUuXG4gICAqL1xuICBzdGF0aWMgZ2V0QWxnZWJyYWljVHlwZSgpIHtcbiAgICByZXR1cm4gQWxnZWJyYWljVHlwZS5Qcm9kdWN0KHtcbiAgICAgIGVsZW1lbnRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcIl9fdGltZV9kdXJhdGlvbl9taWNyb3NfX1wiLFxuICAgICAgICAgIGFsZ2VicmFpY1R5cGU6IEFsZ2VicmFpY1R5cGUuSTY0XG4gICAgICAgIH1cbiAgICAgIF1cbiAgICB9KTtcbiAgfVxuICBzdGF0aWMgaXNUaW1lRHVyYXRpb24oYWxnZWJyYWljVHlwZSkge1xuICAgIGlmIChhbGdlYnJhaWNUeXBlLnRhZyAhPT0gXCJQcm9kdWN0XCIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgZWxlbWVudHMgPSBhbGdlYnJhaWNUeXBlLnZhbHVlLmVsZW1lbnRzO1xuICAgIGlmIChlbGVtZW50cy5sZW5ndGggIT09IDEpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgbWljcm9zRWxlbWVudCA9IGVsZW1lbnRzWzBdO1xuICAgIHJldHVybiBtaWNyb3NFbGVtZW50Lm5hbWUgPT09IFwiX190aW1lX2R1cmF0aW9uX21pY3Jvc19fXCIgJiYgbWljcm9zRWxlbWVudC5hbGdlYnJhaWNUeXBlLnRhZyA9PT0gXCJJNjRcIjtcbiAgfVxuICBnZXQgbWljcm9zKCkge1xuICAgIHJldHVybiB0aGlzLl9fdGltZV9kdXJhdGlvbl9taWNyb3NfXztcbiAgfVxuICBnZXQgbWlsbGlzKCkge1xuICAgIHJldHVybiBOdW1iZXIodGhpcy5taWNyb3MgLyBfVGltZUR1cmF0aW9uLk1JQ1JPU19QRVJfTUlMTElTKTtcbiAgfVxuICBjb25zdHJ1Y3RvcihtaWNyb3MpIHtcbiAgICB0aGlzLl9fdGltZV9kdXJhdGlvbl9taWNyb3NfXyA9IG1pY3JvcztcbiAgfVxuICBzdGF0aWMgZnJvbU1pbGxpcyhtaWxsaXMpIHtcbiAgICByZXR1cm4gbmV3IF9UaW1lRHVyYXRpb24oQmlnSW50KG1pbGxpcykgKiBfVGltZUR1cmF0aW9uLk1JQ1JPU19QRVJfTUlMTElTKTtcbiAgfVxuICAvKiogVGhpcyBvdXRwdXRzIHRoZSBzYW1lIHN0cmluZyBmb3JtYXQgdGhhdCB3ZSB1c2UgaW4gdGhlIGhvc3QgYW5kIGluIFJ1c3QgbW9kdWxlcyAqL1xuICB0b1N0cmluZygpIHtcbiAgICBjb25zdCBtaWNyb3MgPSB0aGlzLm1pY3JvcztcbiAgICBjb25zdCBzaWduID0gbWljcm9zIDwgMCA/IFwiLVwiIDogXCIrXCI7XG4gICAgY29uc3QgcG9zID0gbWljcm9zIDwgMCA/IC1taWNyb3MgOiBtaWNyb3M7XG4gICAgY29uc3Qgc2VjcyA9IHBvcyAvIDEwMDAwMDBuO1xuICAgIGNvbnN0IG1pY3Jvc19yZW1haW5pbmcgPSBwb3MgJSAxMDAwMDAwbjtcbiAgICByZXR1cm4gYCR7c2lnbn0ke3NlY3N9LiR7U3RyaW5nKG1pY3Jvc19yZW1haW5pbmcpLnBhZFN0YXJ0KDYsIFwiMFwiKX1gO1xuICB9XG59O1xuXG4vLyBzcmMvbGliL3RpbWVzdGFtcC50c1xudmFyIFRpbWVzdGFtcCA9IGNsYXNzIF9UaW1lc3RhbXAge1xuICBfX3RpbWVzdGFtcF9taWNyb3Nfc2luY2VfdW5peF9lcG9jaF9fO1xuICBzdGF0aWMgTUlDUk9TX1BFUl9NSUxMSVMgPSAxMDAwbjtcbiAgZ2V0IG1pY3Jvc1NpbmNlVW5peEVwb2NoKCkge1xuICAgIHJldHVybiB0aGlzLl9fdGltZXN0YW1wX21pY3Jvc19zaW5jZV91bml4X2Vwb2NoX187XG4gIH1cbiAgY29uc3RydWN0b3IobWljcm9zKSB7XG4gICAgdGhpcy5fX3RpbWVzdGFtcF9taWNyb3Nfc2luY2VfdW5peF9lcG9jaF9fID0gbWljcm9zO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgdGhlIGFsZ2VicmFpYyB0eXBlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB7QGxpbmsgVGltZXN0YW1wfSB0eXBlLlxuICAgKiBAcmV0dXJucyBUaGUgYWxnZWJyYWljIHR5cGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIHR5cGUuXG4gICAqL1xuICBzdGF0aWMgZ2V0QWxnZWJyYWljVHlwZSgpIHtcbiAgICByZXR1cm4gQWxnZWJyYWljVHlwZS5Qcm9kdWN0KHtcbiAgICAgIGVsZW1lbnRzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcIl9fdGltZXN0YW1wX21pY3Jvc19zaW5jZV91bml4X2Vwb2NoX19cIixcbiAgICAgICAgICBhbGdlYnJhaWNUeXBlOiBBbGdlYnJhaWNUeXBlLkk2NFxuICAgICAgICB9XG4gICAgICBdXG4gICAgfSk7XG4gIH1cbiAgc3RhdGljIGlzVGltZXN0YW1wKGFsZ2VicmFpY1R5cGUpIHtcbiAgICBpZiAoYWxnZWJyYWljVHlwZS50YWcgIT09IFwiUHJvZHVjdFwiKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGVsZW1lbnRzID0gYWxnZWJyYWljVHlwZS52YWx1ZS5lbGVtZW50cztcbiAgICBpZiAoZWxlbWVudHMubGVuZ3RoICE9PSAxKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IG1pY3Jvc0VsZW1lbnQgPSBlbGVtZW50c1swXTtcbiAgICByZXR1cm4gbWljcm9zRWxlbWVudC5uYW1lID09PSBcIl9fdGltZXN0YW1wX21pY3Jvc19zaW5jZV91bml4X2Vwb2NoX19cIiAmJiBtaWNyb3NFbGVtZW50LmFsZ2VicmFpY1R5cGUudGFnID09PSBcIkk2NFwiO1xuICB9XG4gIC8qKlxuICAgKiBUaGUgVW5peCBlcG9jaCwgdGhlIG1pZG5pZ2h0IGF0IHRoZSBiZWdpbm5pbmcgb2YgSmFudWFyeSAxLCAxOTcwLCBVVEMuXG4gICAqL1xuICBzdGF0aWMgVU5JWF9FUE9DSCA9IG5ldyBfVGltZXN0YW1wKDBuKTtcbiAgLyoqXG4gICAqIEdldCBhIGBUaW1lc3RhbXBgIHJlcHJlc2VudGluZyB0aGUgZXhlY3V0aW9uIGVudmlyb25tZW50J3MgYmVsaWVmIG9mIHRoZSBjdXJyZW50IG1vbWVudCBpbiB0aW1lLlxuICAgKi9cbiAgc3RhdGljIG5vdygpIHtcbiAgICByZXR1cm4gX1RpbWVzdGFtcC5mcm9tRGF0ZSgvKiBAX19QVVJFX18gKi8gbmV3IERhdGUoKSk7XG4gIH1cbiAgLyoqIENvbnZlcnQgdG8gbWlsbGlzZWNvbmRzIHNpbmNlIFVuaXggZXBvY2guICovXG4gIHRvTWlsbGlzKCkge1xuICAgIHJldHVybiB0aGlzLm1pY3Jvc1NpbmNlVW5peEVwb2NoIC8gMTAwMG47XG4gIH1cbiAgLyoqXG4gICAqIEdldCBhIGBUaW1lc3RhbXBgIHJlcHJlc2VudGluZyB0aGUgc2FtZSBwb2ludCBpbiB0aW1lIGFzIGBkYXRlYC5cbiAgICovXG4gIHN0YXRpYyBmcm9tRGF0ZShkYXRlKSB7XG4gICAgY29uc3QgbWlsbGlzID0gZGF0ZS5nZXRUaW1lKCk7XG4gICAgY29uc3QgbWljcm9zID0gQmlnSW50KG1pbGxpcykgKiBfVGltZXN0YW1wLk1JQ1JPU19QRVJfTUlMTElTO1xuICAgIHJldHVybiBuZXcgX1RpbWVzdGFtcChtaWNyb3MpO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgYSBgRGF0ZWAgcmVwcmVzZW50aW5nIGFwcHJveGltYXRlbHkgdGhlIHNhbWUgcG9pbnQgaW4gdGltZSBhcyBgdGhpc2AuXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIHRydW5jYXRlcyB0byBtaWxsaXNlY29uZCBwcmVjaXNpb24sXG4gICAqIGFuZCB0aHJvd3MgYFJhbmdlRXJyb3JgIGlmIHRoZSBgVGltZXN0YW1wYCBpcyBvdXRzaWRlIHRoZSByYW5nZSByZXByZXNlbnRhYmxlIGFzIGEgYERhdGVgLlxuICAgKi9cbiAgdG9EYXRlKCkge1xuICAgIGNvbnN0IG1pY3JvcyA9IHRoaXMuX190aW1lc3RhbXBfbWljcm9zX3NpbmNlX3VuaXhfZXBvY2hfXztcbiAgICBjb25zdCBtaWxsaXMgPSBtaWNyb3MgLyBfVGltZXN0YW1wLk1JQ1JPU19QRVJfTUlMTElTO1xuICAgIGlmIChtaWxsaXMgPiBCaWdJbnQoTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIpIHx8IG1pbGxpcyA8IEJpZ0ludChOdW1iZXIuTUlOX1NBRkVfSU5URUdFUikpIHtcbiAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFxuICAgICAgICBcIlRpbWVzdGFtcCBpcyBvdXRzaWRlIG9mIHRoZSByZXByZXNlbnRhYmxlIHJhbmdlIG9mIEpTJ3MgRGF0ZVwiXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IERhdGUoTnVtYmVyKG1pbGxpcykpO1xuICB9XG4gIC8qKlxuICAgKiBHZXQgYW4gSVNPIDg2MDEgLyBSRkMgMzMzOSBmb3JtYXR0ZWQgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgdGltZXN0YW1wIHdpdGggbWljcm9zZWNvbmQgcHJlY2lzaW9uLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBwcmVzZXJ2ZXMgdGhlIGZ1bGwgbWljcm9zZWNvbmQgcHJlY2lzaW9uIG9mIHRoZSB0aW1lc3RhbXAsXG4gICAqIGFuZCB0aHJvd3MgYFJhbmdlRXJyb3JgIGlmIHRoZSBgVGltZXN0YW1wYCBpcyBvdXRzaWRlIHRoZSByYW5nZSByZXByZXNlbnRhYmxlIGluIElTTyBmb3JtYXQuXG4gICAqXG4gICAqIEByZXR1cm5zIElTTyA4NjAxIGZvcm1hdHRlZCBzdHJpbmcgd2l0aCBtaWNyb3NlY29uZCBwcmVjaXNpb24gKGUuZy4sICcyMDI1LTAyLTE3VDEwOjMwOjQ1LjEyMzQ1NlonKVxuICAgKi9cbiAgdG9JU09TdHJpbmcoKSB7XG4gICAgY29uc3QgbWljcm9zID0gdGhpcy5fX3RpbWVzdGFtcF9taWNyb3Nfc2luY2VfdW5peF9lcG9jaF9fO1xuICAgIGNvbnN0IG1pbGxpcyA9IG1pY3JvcyAvIF9UaW1lc3RhbXAuTUlDUk9TX1BFUl9NSUxMSVM7XG4gICAgaWYgKG1pbGxpcyA+IEJpZ0ludChOdW1iZXIuTUFYX1NBRkVfSU5URUdFUikgfHwgbWlsbGlzIDwgQmlnSW50KE51bWJlci5NSU5fU0FGRV9JTlRFR0VSKSkge1xuICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoXG4gICAgICAgIFwiVGltZXN0YW1wIGlzIG91dHNpZGUgb2YgdGhlIHJlcHJlc2VudGFibGUgcmFuZ2UgZm9yIElTTyBzdHJpbmcgZm9ybWF0dGluZ1wiXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoTnVtYmVyKG1pbGxpcykpO1xuICAgIGNvbnN0IGlzb0Jhc2UgPSBkYXRlLnRvSVNPU3RyaW5nKCk7XG4gICAgY29uc3QgbWljcm9zUmVtYWluZGVyID0gTWF0aC5hYnMoTnVtYmVyKG1pY3JvcyAlIDEwMDAwMDBuKSk7XG4gICAgY29uc3QgZnJhY3Rpb25hbFBhcnQgPSBTdHJpbmcobWljcm9zUmVtYWluZGVyKS5wYWRTdGFydCg2LCBcIjBcIik7XG4gICAgcmV0dXJuIGlzb0Jhc2UucmVwbGFjZSgvXFwuXFxkezN9WiQvLCBgLiR7ZnJhY3Rpb25hbFBhcnR9WmApO1xuICB9XG4gIHNpbmNlKG90aGVyKSB7XG4gICAgcmV0dXJuIG5ldyBUaW1lRHVyYXRpb24oXG4gICAgICB0aGlzLl9fdGltZXN0YW1wX21pY3Jvc19zaW5jZV91bml4X2Vwb2NoX18gLSBvdGhlci5fX3RpbWVzdGFtcF9taWNyb3Nfc2luY2VfdW5peF9lcG9jaF9fXG4gICAgKTtcbiAgfVxufTtcblxuLy8gc3JjL2xpYi91dWlkLnRzXG52YXIgVXVpZCA9IGNsYXNzIF9VdWlkIHtcbiAgX191dWlkX187XG4gIC8qKlxuICAgKiBUaGUgbmlsIFVVSUQgKGFsbCB6ZXJvcykuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIGBgYHRzXG4gICAqIGNvbnN0IHV1aWQgPSBVdWlkLk5JTDtcbiAgICogY29uc29sZS5hc3NlcnQoXG4gICAqICAgdXVpZC50b1N0cmluZygpID09PSBcIjAwMDAwMDAwLTAwMDAtMDAwMC0wMDAwLTAwMDAwMDAwMDAwMFwiXG4gICAqICk7XG4gICAqIGBgYFxuICAgKi9cbiAgc3RhdGljIE5JTCA9IG5ldyBfVXVpZCgwbik7XG4gIHN0YXRpYyBNQVhfVVVJRF9CSUdJTlQgPSAweGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmbjtcbiAgLyoqXG4gICAqIFRoZSBtYXggVVVJRCAoYWxsIG9uZXMpLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKiBgYGB0c1xuICAgKiBjb25zdCB1dWlkID0gVXVpZC5NQVg7XG4gICAqIGNvbnNvbGUuYXNzZXJ0KFxuICAgKiAgIHV1aWQudG9TdHJpbmcoKSA9PT0gXCJmZmZmZmZmZi1mZmZmLWZmZmYtZmZmZi1mZmZmZmZmZmZmZmZcIlxuICAgKiApO1xuICAgKiBgYGBcbiAgICovXG4gIHN0YXRpYyBNQVggPSBuZXcgX1V1aWQoX1V1aWQuTUFYX1VVSURfQklHSU5UKTtcbiAgLyoqXG4gICAqIENyZWF0ZSBhIFVVSUQgZnJvbSBhIHJhdyAxMjgtYml0IHZhbHVlLlxuICAgKlxuICAgKiBAcGFyYW0gdSAtIFVuc2lnbmVkIDEyOC1iaXQgaW50ZWdlclxuICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHZhbHVlIGlzIG91dHNpZGUgdGhlIHZhbGlkIFVVSUQgcmFuZ2VcbiAgICovXG4gIGNvbnN0cnVjdG9yKHUpIHtcbiAgICBpZiAodSA8IDBuIHx8IHUgPiBfVXVpZC5NQVhfVVVJRF9CSUdJTlQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgVVVJRDogbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIGBNQVhfVVVJRF9CSUdJTlRgXCIpO1xuICAgIH1cbiAgICB0aGlzLl9fdXVpZF9fID0gdTtcbiAgfVxuICAvKipcbiAgICogQ3JlYXRlIGEgVVVJRCBgdjRgIGZyb20gZXhwbGljaXQgcmFuZG9tIGJ5dGVzLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBhc3N1bWVzIHRoZSBieXRlcyBhcmUgYWxyZWFkeSBzdWZmaWNpZW50bHkgcmFuZG9tLlxuICAgKiBJdCBvbmx5IHNldHMgdGhlIGFwcHJvcHJpYXRlIGJpdHMgZm9yIHRoZSBVVUlEIHZlcnNpb24gYW5kIHZhcmlhbnQuXG4gICAqXG4gICAqIEBwYXJhbSBieXRlcyAtIEV4YWN0bHkgMTYgcmFuZG9tIGJ5dGVzXG4gICAqIEByZXR1cm5zIEEgVVVJRCBgdjRgXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBJZiBgYnl0ZXMubGVuZ3RoICE9PSAxNmBcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHNcbiAgICogY29uc3QgcmFuZG9tQnl0ZXMgPSBuZXcgVWludDhBcnJheSgxNik7XG4gICAqIGNvbnN0IHV1aWQgPSBVdWlkLmZyb21SYW5kb21CeXRlc1Y0KHJhbmRvbUJ5dGVzKTtcbiAgICpcbiAgICogY29uc29sZS5hc3NlcnQoXG4gICAqICAgdXVpZC50b1N0cmluZygpID09PSBcIjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMFwiXG4gICAqICk7XG4gICAqIGBgYFxuICAgKi9cbiAgc3RhdGljIGZyb21SYW5kb21CeXRlc1Y0KGJ5dGVzKSB7XG4gICAgaWYgKGJ5dGVzLmxlbmd0aCAhPT0gMTYpIHRocm93IG5ldyBFcnJvcihcIlVVSUQgdjQgcmVxdWlyZXMgMTYgYnl0ZXNcIik7XG4gICAgY29uc3QgYXJyID0gbmV3IFVpbnQ4QXJyYXkoYnl0ZXMpO1xuICAgIGFycls2XSA9IGFycls2XSAmIDE1IHwgNjQ7XG4gICAgYXJyWzhdID0gYXJyWzhdICYgNjMgfCAxMjg7XG4gICAgcmV0dXJuIG5ldyBfVXVpZChfVXVpZC5ieXRlc1RvQmlnSW50KGFycikpO1xuICB9XG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBhIFVVSUQgYHY3YCB1c2luZyBhIG1vbm90b25pYyBjb3VudGVyIGZyb20gYDBgIHRvIGAyXjMxIC0gMWAsXG4gICAqIGEgdGltZXN0YW1wLCBhbmQgNCByYW5kb20gYnl0ZXMuXG4gICAqXG4gICAqIFRoZSBjb3VudGVyIHdyYXBzIGFyb3VuZCBvbiBvdmVyZmxvdy5cbiAgICpcbiAgICogVGhlIFVVSUQgYHY3YCBpcyBzdHJ1Y3R1cmVkIGFzIGZvbGxvd3M6XG4gICAqXG4gICAqIGBgYGFzY2lpXG4gICAqIOKUjOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUrOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUkFxuICAgKiB8IEIwICB8IEIxICB8IEIyICB8IEIzICB8IEI0ICB8IEI1ICAgICAgICAgICAgICB8ICAgICAgICAgQjYgICAgICAgIHxcbiAgICog4pSc4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pS84pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSkXG4gICAqIHwgICAgICAgICAgICAgICAgIHVuaXhfdHNfbXMgICAgICAgICAgICAgICAgICAgIHwgICAgICB2ZXJzaW9uIDcgICAgfFxuICAgKiDilJTilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilLTilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJhcbiAgICog4pSM4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSs4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSs4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSs4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSQXG4gICAqIHwgQjcgICAgICAgICAgIHwgQjggICAgICB8IEI5ICB8IEIxMCB8IEIxMSAgfCBCMTIgfCBCMTMgfCBCMTQgfCBCMTUgfFxuICAgKiDilJzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilLzilIDilIDilIDilIDilIDilIDilIDilIDilIDilLzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilLzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilKRcbiAgICogfCBjb3VudGVyX2hpZ2ggfCB2YXJpYW50IHwgICAgY291bnRlcl9sb3cgICB8ICAgICAgICByYW5kb20gICAgICAgICB8XG4gICAqIOKUlOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUtOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUtOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUtOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUmFxuICAgKiBgYGBcbiAgICpcbiAgICogQHBhcmFtIGNvdW50ZXIgLSBNdXRhYmxlIG1vbm90b25pYyBjb3VudGVyICgzMS1iaXQpXG4gICAqIEBwYXJhbSBub3cgLSBUaW1lc3RhbXAgc2luY2UgdGhlIFVuaXggZXBvY2hcbiAgICogQHBhcmFtIHJhbmRvbUJ5dGVzIC0gRXhhY3RseSA0IHJhbmRvbSBieXRlc1xuICAgKiBAcmV0dXJucyBBIFVVSUQgYHY3YFxuICAgKlxuICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIGBjb3VudGVyYCBpcyBuZWdhdGl2ZVxuICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIGB0aW1lc3RhbXBgIGlzIGJlZm9yZSB0aGUgVW5peCBlcG9jaFxuICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgYHJhbmRvbUJ5dGVzLmxlbmd0aCAhPT0gNGBcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHNcbiAgICogY29uc3Qgbm93ID0gVGltZXN0YW1wLmZyb21NaWxsaXMoMV82ODZfMDAwXzAwMF8wMDBuKTtcbiAgICogY29uc3QgY291bnRlciA9IHsgdmFsdWU6IDEgfTtcbiAgICogY29uc3QgcmFuZG9tQnl0ZXMgPSBuZXcgVWludDhBcnJheSg0KTtcbiAgICpcbiAgICogY29uc3QgdXVpZCA9IFV1aWQuZnJvbUNvdW50ZXJWNyhjb3VudGVyLCBub3csIHJhbmRvbUJ5dGVzKTtcbiAgICpcbiAgICogY29uc29sZS5hc3NlcnQoXG4gICAqICAgdXVpZC50b1N0cmluZygpID09PSBcIjAwMDA2NDdlLTUxODAtNzAwMC04MDAwLTAwMDIwMDAwMDAwMFwiXG4gICAqICk7XG4gICAqIGBgYFxuICAgKi9cbiAgc3RhdGljIGZyb21Db3VudGVyVjcoY291bnRlciwgbm93LCByYW5kb21CeXRlcykge1xuICAgIGlmIChyYW5kb21CeXRlcy5sZW5ndGggIT09IDQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImBmcm9tQ291bnRlclY3YCByZXF1aXJlcyBgcmFuZG9tQnl0ZXMubGVuZ3RoID09IDRgXCIpO1xuICAgIH1cbiAgICBpZiAoY291bnRlci52YWx1ZSA8IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcImBmcm9tQ291bnRlclY3YCB1dWlkIGBjb3VudGVyYCBtdXN0IGJlIG5vbi1uZWdhdGl2ZVwiKTtcbiAgICB9XG4gICAgaWYgKG5vdy5fX3RpbWVzdGFtcF9taWNyb3Nfc2luY2VfdW5peF9lcG9jaF9fIDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiYGZyb21Db3VudGVyVjdgIGB0aW1lc3RhbXBgIGJlZm9yZSB1bml4IGVwb2NoXCIpO1xuICAgIH1cbiAgICBjb25zdCBjb3VudGVyVmFsID0gY291bnRlci52YWx1ZTtcbiAgICBjb3VudGVyLnZhbHVlID0gY291bnRlclZhbCArIDEgJiAyMTQ3NDgzNjQ3O1xuICAgIGNvbnN0IHRzTXMgPSBub3cudG9NaWxsaXMoKSAmIDB4ZmZmZmZmZmZmZmZmbjtcbiAgICBjb25zdCBieXRlcyA9IG5ldyBVaW50OEFycmF5KDE2KTtcbiAgICBieXRlc1swXSA9IE51bWJlcih0c01zID4+IDQwbiAmIDB4ZmZuKTtcbiAgICBieXRlc1sxXSA9IE51bWJlcih0c01zID4+IDMybiAmIDB4ZmZuKTtcbiAgICBieXRlc1syXSA9IE51bWJlcih0c01zID4+IDI0biAmIDB4ZmZuKTtcbiAgICBieXRlc1szXSA9IE51bWJlcih0c01zID4+IDE2biAmIDB4ZmZuKTtcbiAgICBieXRlc1s0XSA9IE51bWJlcih0c01zID4+IDhuICYgMHhmZm4pO1xuICAgIGJ5dGVzWzVdID0gTnVtYmVyKHRzTXMgJiAweGZmbik7XG4gICAgYnl0ZXNbN10gPSBjb3VudGVyVmFsID4+PiAyMyAmIDI1NTtcbiAgICBieXRlc1s5XSA9IGNvdW50ZXJWYWwgPj4+IDE1ICYgMjU1O1xuICAgIGJ5dGVzWzEwXSA9IGNvdW50ZXJWYWwgPj4+IDcgJiAyNTU7XG4gICAgYnl0ZXNbMTFdID0gKGNvdW50ZXJWYWwgJiAxMjcpIDw8IDEgJiAyNTU7XG4gICAgYnl0ZXNbMTJdIHw9IHJhbmRvbUJ5dGVzWzBdICYgMTI3O1xuICAgIGJ5dGVzWzEzXSA9IHJhbmRvbUJ5dGVzWzFdO1xuICAgIGJ5dGVzWzE0XSA9IHJhbmRvbUJ5dGVzWzJdO1xuICAgIGJ5dGVzWzE1XSA9IHJhbmRvbUJ5dGVzWzNdO1xuICAgIGJ5dGVzWzZdID0gYnl0ZXNbNl0gJiAxNSB8IDExMjtcbiAgICBieXRlc1s4XSA9IGJ5dGVzWzhdICYgNjMgfCAxMjg7XG4gICAgcmV0dXJuIG5ldyBfVXVpZChfVXVpZC5ieXRlc1RvQmlnSW50KGJ5dGVzKSk7XG4gIH1cbiAgLyoqXG4gICAqIFBhcnNlIGEgVVVJRCBmcm9tIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gcyAtIFVVSUQgc3RyaW5nXG4gICAqIEByZXR1cm5zIFBhcnNlZCBVVUlEXG4gICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgc3RyaW5nIGlzIG5vdCBhIHZhbGlkIFVVSURcbiAgICpcbiAgICogQGV4YW1wbGVcbiAgICogYGBgdHNcbiAgICogY29uc3QgcyA9IFwiMDE4ODhkNmUtNWMwMC03MDAwLTgwMDAtMDAwMDAwMDAwMDAwXCI7XG4gICAqIGNvbnN0IHV1aWQgPSBVdWlkLnBhcnNlKHMpO1xuICAgKlxuICAgKiBjb25zb2xlLmFzc2VydCh1dWlkLnRvU3RyaW5nKCkgPT09IHMpO1xuICAgKiBgYGBcbiAgICovXG4gIHN0YXRpYyBwYXJzZShzKSB7XG4gICAgY29uc3QgaGV4ID0gcy5yZXBsYWNlKC8tL2csIFwiXCIpO1xuICAgIGlmIChoZXgubGVuZ3RoICE9PSAzMikgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBoZXggVVVJRFwiKTtcbiAgICBsZXQgdiA9IDBuO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMzI7IGkgKz0gMikge1xuICAgICAgdiA9IHYgPDwgOG4gfCBCaWdJbnQocGFyc2VJbnQoaGV4LnNsaWNlKGksIGkgKyAyKSwgMTYpKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBfVXVpZCh2KTtcbiAgfVxuICAvKiogQ29udmVydCB0byBzdHJpbmcgKGh5cGhlbmF0ZWQgZm9ybSkuICovXG4gIHRvU3RyaW5nKCkge1xuICAgIGNvbnN0IGJ5dGVzID0gX1V1aWQuYmlnSW50VG9CeXRlcyh0aGlzLl9fdXVpZF9fKTtcbiAgICBjb25zdCBoZXggPSBbLi4uYnl0ZXNdLm1hcCgoYikgPT4gYi50b1N0cmluZygxNikucGFkU3RhcnQoMiwgXCIwXCIpKS5qb2luKFwiXCIpO1xuICAgIHJldHVybiBoZXguc2xpY2UoMCwgOCkgKyBcIi1cIiArIGhleC5zbGljZSg4LCAxMikgKyBcIi1cIiArIGhleC5zbGljZSgxMiwgMTYpICsgXCItXCIgKyBoZXguc2xpY2UoMTYsIDIwKSArIFwiLVwiICsgaGV4LnNsaWNlKDIwKTtcbiAgfVxuICAvKiogQ29udmVydCB0byBiaWdpbnQgKHUxMjgpLiAqL1xuICBhc0JpZ0ludCgpIHtcbiAgICByZXR1cm4gdGhpcy5fX3V1aWRfXztcbiAgfVxuICAvKiogUmV0dXJuIGEgYFVpbnQ4QXJyYXlgIG9mIDE2IGJ5dGVzLiAqL1xuICB0b0J5dGVzKCkge1xuICAgIHJldHVybiBfVXVpZC5iaWdJbnRUb0J5dGVzKHRoaXMuX191dWlkX18pO1xuICB9XG4gIHN0YXRpYyBieXRlc1RvQmlnSW50KGJ5dGVzKSB7XG4gICAgbGV0IHJlc3VsdCA9IDBuO1xuICAgIGZvciAoY29uc3QgYiBvZiBieXRlcykgcmVzdWx0ID0gcmVzdWx0IDw8IDhuIHwgQmlnSW50KGIpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbiAgc3RhdGljIGJpZ0ludFRvQnl0ZXModmFsdWUpIHtcbiAgICBjb25zdCBieXRlcyA9IG5ldyBVaW50OEFycmF5KDE2KTtcbiAgICBmb3IgKGxldCBpID0gMTU7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBieXRlc1tpXSA9IE51bWJlcih2YWx1ZSAmIDB4ZmZuKTtcbiAgICAgIHZhbHVlID4+PSA4bjtcbiAgICB9XG4gICAgcmV0dXJuIGJ5dGVzO1xuICB9XG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSB2ZXJzaW9uIG9mIHRoaXMgVVVJRC5cbiAgICpcbiAgICogVGhpcyByZXByZXNlbnRzIHRoZSBhbGdvcml0aG0gdXNlZCB0byBnZW5lcmF0ZSB0aGUgdmFsdWUuXG4gICAqXG4gICAqIEByZXR1cm5zIEEgYFV1aWRWZXJzaW9uYFxuICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIHZlcnNpb24gZmllbGQgaXMgbm90IHJlY29nbml6ZWRcbiAgICovXG4gIGdldFZlcnNpb24oKSB7XG4gICAgY29uc3QgdmVyc2lvbiA9IHRoaXMudG9CeXRlcygpWzZdID4+IDQgJiAxNTtcbiAgICBzd2l0Y2ggKHZlcnNpb24pIHtcbiAgICAgIGNhc2UgNDpcbiAgICAgICAgcmV0dXJuIFwiVjRcIjtcbiAgICAgIGNhc2UgNzpcbiAgICAgICAgcmV0dXJuIFwiVjdcIjtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmICh0aGlzID09IF9VdWlkLk5JTCkge1xuICAgICAgICAgIHJldHVybiBcIk5pbFwiO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzID09IF9VdWlkLk1BWCkge1xuICAgICAgICAgIHJldHVybiBcIk1heFwiO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgVVVJRCB2ZXJzaW9uOiAke3ZlcnNpb259YCk7XG4gICAgfVxuICB9XG4gIC8qKlxuICAgKiBFeHRyYWN0IHRoZSBtb25vdG9uaWMgY291bnRlciBmcm9tIGEgVVVJRHY3LlxuICAgKlxuICAgKiBJbnRlbmRlZCBmb3IgdGVzdGluZyBhbmQgZGlhZ25vc3RpY3MuXG4gICAqIEJlaGF2aW9yIGlzIHVuZGVmaW5lZCBpZiBjYWxsZWQgb24gYSBub24tVjcgVVVJRC5cbiAgICpcbiAgICogQHJldHVybnMgMzEtYml0IGNvdW50ZXIgdmFsdWVcbiAgICovXG4gIGdldENvdW50ZXIoKSB7XG4gICAgY29uc3QgYnl0ZXMgPSB0aGlzLnRvQnl0ZXMoKTtcbiAgICBjb25zdCBoaWdoID0gYnl0ZXNbN107XG4gICAgY29uc3QgbWlkMSA9IGJ5dGVzWzldO1xuICAgIGNvbnN0IG1pZDIgPSBieXRlc1sxMF07XG4gICAgY29uc3QgbG93ID0gYnl0ZXNbMTFdID4+PiAxO1xuICAgIHJldHVybiBoaWdoIDw8IDIzIHwgbWlkMSA8PCAxNSB8IG1pZDIgPDwgNyB8IGxvdyB8IDA7XG4gIH1cbiAgY29tcGFyZVRvKG90aGVyKSB7XG4gICAgaWYgKHRoaXMuX191dWlkX18gPCBvdGhlci5fX3V1aWRfXykgcmV0dXJuIC0xO1xuICAgIGlmICh0aGlzLl9fdXVpZF9fID4gb3RoZXIuX191dWlkX18pIHJldHVybiAxO1xuICAgIHJldHVybiAwO1xuICB9XG4gIHN0YXRpYyBnZXRBbGdlYnJhaWNUeXBlKCkge1xuICAgIHJldHVybiBBbGdlYnJhaWNUeXBlLlByb2R1Y3Qoe1xuICAgICAgZWxlbWVudHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwiX191dWlkX19cIixcbiAgICAgICAgICBhbGdlYnJhaWNUeXBlOiBBbGdlYnJhaWNUeXBlLlUxMjhcbiAgICAgICAgfVxuICAgICAgXVxuICAgIH0pO1xuICB9XG59O1xuXG4vLyBzcmMvbGliL2JpbmFyeV9yZWFkZXIudHNcbnZhciBCaW5hcnlSZWFkZXIgPSBjbGFzcyB7XG4gIC8qKlxuICAgKiBUaGUgRGF0YVZpZXcgdXNlZCB0byByZWFkIHZhbHVlcyBmcm9tIHRoZSBiaW5hcnkgZGF0YS5cbiAgICpcbiAgICogTm90ZTogVGhlIERhdGFWaWV3J3MgYGJ5dGVPZmZzZXRgIGlzIHJlbGF0aXZlIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlXG4gICAqIHVuZGVybHlpbmcgQXJyYXlCdWZmZXIsIG5vdCB0aGUgc3RhcnQgb2YgdGhlIHByb3ZpZGVkIFVpbnQ4QXJyYXkgaW5wdXQuXG4gICAqIFRoaXMgYEJpbmFyeVJlYWRlcmAncyBgI29mZnNldGAgZmllbGQgaXMgdXNlZCB0byB0cmFjayB0aGUgY3VycmVudCByZWFkIHBvc2l0aW9uXG4gICAqIHJlbGF0aXZlIHRvIHRoZSBzdGFydCBvZiB0aGUgcHJvdmlkZWQgVWludDhBcnJheSBpbnB1dC5cbiAgICovXG4gIHZpZXc7XG4gIC8qKlxuICAgKiBSZXByZXNlbnRzIHRoZSBvZmZzZXQgKGluIGJ5dGVzKSByZWxhdGl2ZSB0byB0aGUgc3RhcnQgb2YgdGhlIERhdGFWaWV3XG4gICAqIGFuZCBwcm92aWRlZCBVaW50OEFycmF5IGlucHV0LlxuICAgKlxuICAgKiBOb3RlOiBUaGlzIGlzICpub3QqIHRoZSBhYnNvbHV0ZSBieXRlIG9mZnNldCB3aXRoaW4gdGhlIHVuZGVybHlpbmcgQXJyYXlCdWZmZXIuXG4gICAqL1xuICBvZmZzZXQgPSAwO1xuICBjb25zdHJ1Y3RvcihpbnB1dCkge1xuICAgIHRoaXMudmlldyA9IGlucHV0IGluc3RhbmNlb2YgRGF0YVZpZXcgPyBpbnB1dCA6IG5ldyBEYXRhVmlldyhpbnB1dC5idWZmZXIsIGlucHV0LmJ5dGVPZmZzZXQsIGlucHV0LmJ5dGVMZW5ndGgpO1xuICAgIHRoaXMub2Zmc2V0ID0gMDtcbiAgfVxuICByZXNldCh2aWV3KSB7XG4gICAgdGhpcy52aWV3ID0gdmlldztcbiAgICB0aGlzLm9mZnNldCA9IDA7XG4gIH1cbiAgZ2V0IHJlbWFpbmluZygpIHtcbiAgICByZXR1cm4gdGhpcy52aWV3LmJ5dGVMZW5ndGggLSB0aGlzLm9mZnNldDtcbiAgfVxuICAvKiogRW5zdXJlIHdlIGhhdmUgYXQgbGVhc3QgYG5gIGJ5dGVzIGxlZnQgdG8gcmVhZCAqL1xuICAjZW5zdXJlKG4pIHtcbiAgICBpZiAodGhpcy5vZmZzZXQgKyBuID4gdGhpcy52aWV3LmJ5dGVMZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKFxuICAgICAgICBgVHJpZWQgdG8gcmVhZCAke259IGJ5dGUocykgYXQgcmVsYXRpdmUgb2Zmc2V0ICR7dGhpcy5vZmZzZXR9LCBidXQgb25seSAke3RoaXMucmVtYWluaW5nfSBieXRlKHMpIHJlbWFpbmBcbiAgICAgICk7XG4gICAgfVxuICB9XG4gIHJlYWRVSW50OEFycmF5KCkge1xuICAgIGNvbnN0IGxlbmd0aCA9IHRoaXMucmVhZFUzMigpO1xuICAgIHRoaXMuI2Vuc3VyZShsZW5ndGgpO1xuICAgIHJldHVybiB0aGlzLnJlYWRCeXRlcyhsZW5ndGgpO1xuICB9XG4gIHJlYWRCb29sKCkge1xuICAgIGNvbnN0IHZhbHVlID0gdGhpcy52aWV3LmdldFVpbnQ4KHRoaXMub2Zmc2V0KTtcbiAgICB0aGlzLm9mZnNldCArPSAxO1xuICAgIHJldHVybiB2YWx1ZSAhPT0gMDtcbiAgfVxuICByZWFkQnl0ZSgpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMudmlldy5nZXRVaW50OCh0aGlzLm9mZnNldCk7XG4gICAgdGhpcy5vZmZzZXQgKz0gMTtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgcmVhZEJ5dGVzKGxlbmd0aCkge1xuICAgIGNvbnN0IGFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoXG4gICAgICB0aGlzLnZpZXcuYnVmZmVyLFxuICAgICAgdGhpcy52aWV3LmJ5dGVPZmZzZXQgKyB0aGlzLm9mZnNldCxcbiAgICAgIGxlbmd0aFxuICAgICk7XG4gICAgdGhpcy5vZmZzZXQgKz0gbGVuZ3RoO1xuICAgIHJldHVybiBhcnJheTtcbiAgfVxuICByZWFkSTgoKSB7XG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLnZpZXcuZ2V0SW50OCh0aGlzLm9mZnNldCk7XG4gICAgdGhpcy5vZmZzZXQgKz0gMTtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgcmVhZFU4KCkge1xuICAgIHJldHVybiB0aGlzLnJlYWRCeXRlKCk7XG4gIH1cbiAgcmVhZEkxNigpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMudmlldy5nZXRJbnQxNih0aGlzLm9mZnNldCwgdHJ1ZSk7XG4gICAgdGhpcy5vZmZzZXQgKz0gMjtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgcmVhZFUxNigpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMudmlldy5nZXRVaW50MTYodGhpcy5vZmZzZXQsIHRydWUpO1xuICAgIHRoaXMub2Zmc2V0ICs9IDI7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIHJlYWRJMzIoKSB7XG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLnZpZXcuZ2V0SW50MzIodGhpcy5vZmZzZXQsIHRydWUpO1xuICAgIHRoaXMub2Zmc2V0ICs9IDQ7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIHJlYWRVMzIoKSB7XG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLnZpZXcuZ2V0VWludDMyKHRoaXMub2Zmc2V0LCB0cnVlKTtcbiAgICB0aGlzLm9mZnNldCArPSA0O1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICByZWFkSTY0KCkge1xuICAgIGNvbnN0IHZhbHVlID0gdGhpcy52aWV3LmdldEJpZ0ludDY0KHRoaXMub2Zmc2V0LCB0cnVlKTtcbiAgICB0aGlzLm9mZnNldCArPSA4O1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICByZWFkVTY0KCkge1xuICAgIGNvbnN0IHZhbHVlID0gdGhpcy52aWV3LmdldEJpZ1VpbnQ2NCh0aGlzLm9mZnNldCwgdHJ1ZSk7XG4gICAgdGhpcy5vZmZzZXQgKz0gODtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgcmVhZFUxMjgoKSB7XG4gICAgY29uc3QgbG93ZXJQYXJ0ID0gdGhpcy52aWV3LmdldEJpZ1VpbnQ2NCh0aGlzLm9mZnNldCwgdHJ1ZSk7XG4gICAgY29uc3QgdXBwZXJQYXJ0ID0gdGhpcy52aWV3LmdldEJpZ1VpbnQ2NCh0aGlzLm9mZnNldCArIDgsIHRydWUpO1xuICAgIHRoaXMub2Zmc2V0ICs9IDE2O1xuICAgIHJldHVybiAodXBwZXJQYXJ0IDw8IEJpZ0ludCg2NCkpICsgbG93ZXJQYXJ0O1xuICB9XG4gIHJlYWRJMTI4KCkge1xuICAgIGNvbnN0IGxvd2VyUGFydCA9IHRoaXMudmlldy5nZXRCaWdVaW50NjQodGhpcy5vZmZzZXQsIHRydWUpO1xuICAgIGNvbnN0IHVwcGVyUGFydCA9IHRoaXMudmlldy5nZXRCaWdJbnQ2NCh0aGlzLm9mZnNldCArIDgsIHRydWUpO1xuICAgIHRoaXMub2Zmc2V0ICs9IDE2O1xuICAgIHJldHVybiAodXBwZXJQYXJ0IDw8IEJpZ0ludCg2NCkpICsgbG93ZXJQYXJ0O1xuICB9XG4gIHJlYWRVMjU2KCkge1xuICAgIGNvbnN0IHAwID0gdGhpcy52aWV3LmdldEJpZ1VpbnQ2NCh0aGlzLm9mZnNldCwgdHJ1ZSk7XG4gICAgY29uc3QgcDEgPSB0aGlzLnZpZXcuZ2V0QmlnVWludDY0KHRoaXMub2Zmc2V0ICsgOCwgdHJ1ZSk7XG4gICAgY29uc3QgcDIgPSB0aGlzLnZpZXcuZ2V0QmlnVWludDY0KHRoaXMub2Zmc2V0ICsgMTYsIHRydWUpO1xuICAgIGNvbnN0IHAzID0gdGhpcy52aWV3LmdldEJpZ1VpbnQ2NCh0aGlzLm9mZnNldCArIDI0LCB0cnVlKTtcbiAgICB0aGlzLm9mZnNldCArPSAzMjtcbiAgICByZXR1cm4gKHAzIDw8IEJpZ0ludCgzICogNjQpKSArIChwMiA8PCBCaWdJbnQoMiAqIDY0KSkgKyAocDEgPDwgQmlnSW50KDEgKiA2NCkpICsgcDA7XG4gIH1cbiAgcmVhZEkyNTYoKSB7XG4gICAgY29uc3QgcDAgPSB0aGlzLnZpZXcuZ2V0QmlnVWludDY0KHRoaXMub2Zmc2V0LCB0cnVlKTtcbiAgICBjb25zdCBwMSA9IHRoaXMudmlldy5nZXRCaWdVaW50NjQodGhpcy5vZmZzZXQgKyA4LCB0cnVlKTtcbiAgICBjb25zdCBwMiA9IHRoaXMudmlldy5nZXRCaWdVaW50NjQodGhpcy5vZmZzZXQgKyAxNiwgdHJ1ZSk7XG4gICAgY29uc3QgcDMgPSB0aGlzLnZpZXcuZ2V0QmlnSW50NjQodGhpcy5vZmZzZXQgKyAyNCwgdHJ1ZSk7XG4gICAgdGhpcy5vZmZzZXQgKz0gMzI7XG4gICAgcmV0dXJuIChwMyA8PCBCaWdJbnQoMyAqIDY0KSkgKyAocDIgPDwgQmlnSW50KDIgKiA2NCkpICsgKHAxIDw8IEJpZ0ludCgxICogNjQpKSArIHAwO1xuICB9XG4gIHJlYWRGMzIoKSB7XG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLnZpZXcuZ2V0RmxvYXQzMih0aGlzLm9mZnNldCwgdHJ1ZSk7XG4gICAgdGhpcy5vZmZzZXQgKz0gNDtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgcmVhZEY2NCgpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMudmlldy5nZXRGbG9hdDY0KHRoaXMub2Zmc2V0LCB0cnVlKTtcbiAgICB0aGlzLm9mZnNldCArPSA4O1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICByZWFkU3RyaW5nKCkge1xuICAgIGNvbnN0IHVpbnQ4QXJyYXkgPSB0aGlzLnJlYWRVSW50OEFycmF5KCk7XG4gICAgcmV0dXJuIG5ldyBUZXh0RGVjb2RlcihcInV0Zi04XCIpLmRlY29kZSh1aW50OEFycmF5KTtcbiAgfVxufTtcblxuLy8gc3JjL2xpYi9iaW5hcnlfd3JpdGVyLnRzXG52YXIgaW1wb3J0X2Jhc2U2NF9qcyA9IF9fdG9FU00ocmVxdWlyZV9iYXNlNjRfanMoKSk7XG52YXIgQXJyYXlCdWZmZXJQcm90b3R5cGVUcmFuc2ZlciA9IEFycmF5QnVmZmVyLnByb3RvdHlwZS50cmFuc2ZlciA/PyBmdW5jdGlvbihuZXdCeXRlTGVuZ3RoKSB7XG4gIGlmIChuZXdCeXRlTGVuZ3RoID09PSB2b2lkIDApIHtcbiAgICByZXR1cm4gdGhpcy5zbGljZSgpO1xuICB9IGVsc2UgaWYgKG5ld0J5dGVMZW5ndGggPD0gdGhpcy5ieXRlTGVuZ3RoKSB7XG4gICAgcmV0dXJuIHRoaXMuc2xpY2UoMCwgbmV3Qnl0ZUxlbmd0aCk7XG4gIH0gZWxzZSB7XG4gICAgY29uc3QgY29weSA9IG5ldyBVaW50OEFycmF5KG5ld0J5dGVMZW5ndGgpO1xuICAgIGNvcHkuc2V0KG5ldyBVaW50OEFycmF5KHRoaXMpKTtcbiAgICByZXR1cm4gY29weS5idWZmZXI7XG4gIH1cbn07XG52YXIgUmVzaXphYmxlQnVmZmVyID0gY2xhc3Mge1xuICBidWZmZXI7XG4gIHZpZXc7XG4gIGNvbnN0cnVjdG9yKGluaXQpIHtcbiAgICB0aGlzLmJ1ZmZlciA9IHR5cGVvZiBpbml0ID09PSBcIm51bWJlclwiID8gbmV3IEFycmF5QnVmZmVyKGluaXQpIDogaW5pdDtcbiAgICB0aGlzLnZpZXcgPSBuZXcgRGF0YVZpZXcodGhpcy5idWZmZXIpO1xuICB9XG4gIGdldCBjYXBhY2l0eSgpIHtcbiAgICByZXR1cm4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDtcbiAgfVxuICBncm93KG5ld1NpemUpIHtcbiAgICBpZiAobmV3U2l6ZSA8PSB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKSByZXR1cm47XG4gICAgdGhpcy5idWZmZXIgPSBBcnJheUJ1ZmZlclByb3RvdHlwZVRyYW5zZmVyLmNhbGwodGhpcy5idWZmZXIsIG5ld1NpemUpO1xuICAgIHRoaXMudmlldyA9IG5ldyBEYXRhVmlldyh0aGlzLmJ1ZmZlcik7XG4gIH1cbn07XG52YXIgQmluYXJ5V3JpdGVyID0gY2xhc3Mge1xuICBidWZmZXI7XG4gIG9mZnNldCA9IDA7XG4gIGNvbnN0cnVjdG9yKGluaXQpIHtcbiAgICB0aGlzLmJ1ZmZlciA9IHR5cGVvZiBpbml0ID09PSBcIm51bWJlclwiID8gbmV3IFJlc2l6YWJsZUJ1ZmZlcihpbml0KSA6IGluaXQ7XG4gIH1cbiAgY2xlYXIoKSB7XG4gICAgdGhpcy5vZmZzZXQgPSAwO1xuICB9XG4gIHJlc2V0KGJ1ZmZlcikge1xuICAgIHRoaXMuYnVmZmVyID0gYnVmZmVyO1xuICAgIHRoaXMub2Zmc2V0ID0gMDtcbiAgfVxuICBleHBhbmRCdWZmZXIoYWRkaXRpb25hbENhcGFjaXR5KSB7XG4gICAgY29uc3QgbWluQ2FwYWNpdHkgPSB0aGlzLm9mZnNldCArIGFkZGl0aW9uYWxDYXBhY2l0eSArIDE7XG4gICAgaWYgKG1pbkNhcGFjaXR5IDw9IHRoaXMuYnVmZmVyLmNhcGFjaXR5KSByZXR1cm47XG4gICAgbGV0IG5ld0NhcGFjaXR5ID0gdGhpcy5idWZmZXIuY2FwYWNpdHkgKiAyO1xuICAgIGlmIChuZXdDYXBhY2l0eSA8IG1pbkNhcGFjaXR5KSBuZXdDYXBhY2l0eSA9IG1pbkNhcGFjaXR5O1xuICAgIHRoaXMuYnVmZmVyLmdyb3cobmV3Q2FwYWNpdHkpO1xuICB9XG4gIHRvQmFzZTY0KCkge1xuICAgIHJldHVybiAoMCwgaW1wb3J0X2Jhc2U2NF9qcy5mcm9tQnl0ZUFycmF5KSh0aGlzLmdldEJ1ZmZlcigpKTtcbiAgfVxuICBnZXRCdWZmZXIoKSB7XG4gICAgcmV0dXJuIG5ldyBVaW50OEFycmF5KHRoaXMuYnVmZmVyLmJ1ZmZlciwgMCwgdGhpcy5vZmZzZXQpO1xuICB9XG4gIGdldCB2aWV3KCkge1xuICAgIHJldHVybiB0aGlzLmJ1ZmZlci52aWV3O1xuICB9XG4gIHdyaXRlVUludDhBcnJheSh2YWx1ZSkge1xuICAgIGNvbnN0IGxlbmd0aCA9IHZhbHVlLmxlbmd0aDtcbiAgICB0aGlzLmV4cGFuZEJ1ZmZlcig0ICsgbGVuZ3RoKTtcbiAgICB0aGlzLndyaXRlVTMyKGxlbmd0aCk7XG4gICAgbmV3IFVpbnQ4QXJyYXkodGhpcy5idWZmZXIuYnVmZmVyLCB0aGlzLm9mZnNldCkuc2V0KHZhbHVlKTtcbiAgICB0aGlzLm9mZnNldCArPSBsZW5ndGg7XG4gIH1cbiAgd3JpdGVCb29sKHZhbHVlKSB7XG4gICAgdGhpcy5leHBhbmRCdWZmZXIoMSk7XG4gICAgdGhpcy52aWV3LnNldFVpbnQ4KHRoaXMub2Zmc2V0LCB2YWx1ZSA/IDEgOiAwKTtcbiAgICB0aGlzLm9mZnNldCArPSAxO1xuICB9XG4gIHdyaXRlQnl0ZSh2YWx1ZSkge1xuICAgIHRoaXMuZXhwYW5kQnVmZmVyKDEpO1xuICAgIHRoaXMudmlldy5zZXRVaW50OCh0aGlzLm9mZnNldCwgdmFsdWUpO1xuICAgIHRoaXMub2Zmc2V0ICs9IDE7XG4gIH1cbiAgd3JpdGVJOCh2YWx1ZSkge1xuICAgIHRoaXMuZXhwYW5kQnVmZmVyKDEpO1xuICAgIHRoaXMudmlldy5zZXRJbnQ4KHRoaXMub2Zmc2V0LCB2YWx1ZSk7XG4gICAgdGhpcy5vZmZzZXQgKz0gMTtcbiAgfVxuICB3cml0ZVU4KHZhbHVlKSB7XG4gICAgdGhpcy5leHBhbmRCdWZmZXIoMSk7XG4gICAgdGhpcy52aWV3LnNldFVpbnQ4KHRoaXMub2Zmc2V0LCB2YWx1ZSk7XG4gICAgdGhpcy5vZmZzZXQgKz0gMTtcbiAgfVxuICB3cml0ZUkxNih2YWx1ZSkge1xuICAgIHRoaXMuZXhwYW5kQnVmZmVyKDIpO1xuICAgIHRoaXMudmlldy5zZXRJbnQxNih0aGlzLm9mZnNldCwgdmFsdWUsIHRydWUpO1xuICAgIHRoaXMub2Zmc2V0ICs9IDI7XG4gIH1cbiAgd3JpdGVVMTYodmFsdWUpIHtcbiAgICB0aGlzLmV4cGFuZEJ1ZmZlcigyKTtcbiAgICB0aGlzLnZpZXcuc2V0VWludDE2KHRoaXMub2Zmc2V0LCB2YWx1ZSwgdHJ1ZSk7XG4gICAgdGhpcy5vZmZzZXQgKz0gMjtcbiAgfVxuICB3cml0ZUkzMih2YWx1ZSkge1xuICAgIHRoaXMuZXhwYW5kQnVmZmVyKDQpO1xuICAgIHRoaXMudmlldy5zZXRJbnQzMih0aGlzLm9mZnNldCwgdmFsdWUsIHRydWUpO1xuICAgIHRoaXMub2Zmc2V0ICs9IDQ7XG4gIH1cbiAgd3JpdGVVMzIodmFsdWUpIHtcbiAgICB0aGlzLmV4cGFuZEJ1ZmZlcig0KTtcbiAgICB0aGlzLnZpZXcuc2V0VWludDMyKHRoaXMub2Zmc2V0LCB2YWx1ZSwgdHJ1ZSk7XG4gICAgdGhpcy5vZmZzZXQgKz0gNDtcbiAgfVxuICB3cml0ZUk2NCh2YWx1ZSkge1xuICAgIHRoaXMuZXhwYW5kQnVmZmVyKDgpO1xuICAgIHRoaXMudmlldy5zZXRCaWdJbnQ2NCh0aGlzLm9mZnNldCwgdmFsdWUsIHRydWUpO1xuICAgIHRoaXMub2Zmc2V0ICs9IDg7XG4gIH1cbiAgd3JpdGVVNjQodmFsdWUpIHtcbiAgICB0aGlzLmV4cGFuZEJ1ZmZlcig4KTtcbiAgICB0aGlzLnZpZXcuc2V0QmlnVWludDY0KHRoaXMub2Zmc2V0LCB2YWx1ZSwgdHJ1ZSk7XG4gICAgdGhpcy5vZmZzZXQgKz0gODtcbiAgfVxuICB3cml0ZVUxMjgodmFsdWUpIHtcbiAgICB0aGlzLmV4cGFuZEJ1ZmZlcigxNik7XG4gICAgY29uc3QgbG93ZXJQYXJ0ID0gdmFsdWUgJiBCaWdJbnQoXCIweEZGRkZGRkZGRkZGRkZGRkZcIik7XG4gICAgY29uc3QgdXBwZXJQYXJ0ID0gdmFsdWUgPj4gQmlnSW50KDY0KTtcbiAgICB0aGlzLnZpZXcuc2V0QmlnVWludDY0KHRoaXMub2Zmc2V0LCBsb3dlclBhcnQsIHRydWUpO1xuICAgIHRoaXMudmlldy5zZXRCaWdVaW50NjQodGhpcy5vZmZzZXQgKyA4LCB1cHBlclBhcnQsIHRydWUpO1xuICAgIHRoaXMub2Zmc2V0ICs9IDE2O1xuICB9XG4gIHdyaXRlSTEyOCh2YWx1ZSkge1xuICAgIHRoaXMuZXhwYW5kQnVmZmVyKDE2KTtcbiAgICBjb25zdCBsb3dlclBhcnQgPSB2YWx1ZSAmIEJpZ0ludChcIjB4RkZGRkZGRkZGRkZGRkZGRlwiKTtcbiAgICBjb25zdCB1cHBlclBhcnQgPSB2YWx1ZSA+PiBCaWdJbnQoNjQpO1xuICAgIHRoaXMudmlldy5zZXRCaWdJbnQ2NCh0aGlzLm9mZnNldCwgbG93ZXJQYXJ0LCB0cnVlKTtcbiAgICB0aGlzLnZpZXcuc2V0QmlnSW50NjQodGhpcy5vZmZzZXQgKyA4LCB1cHBlclBhcnQsIHRydWUpO1xuICAgIHRoaXMub2Zmc2V0ICs9IDE2O1xuICB9XG4gIHdyaXRlVTI1Nih2YWx1ZSkge1xuICAgIHRoaXMuZXhwYW5kQnVmZmVyKDMyKTtcbiAgICBjb25zdCBsb3dfNjRfbWFzayA9IEJpZ0ludChcIjB4RkZGRkZGRkZGRkZGRkZGRlwiKTtcbiAgICBjb25zdCBwMCA9IHZhbHVlICYgbG93XzY0X21hc2s7XG4gICAgY29uc3QgcDEgPSB2YWx1ZSA+PiBCaWdJbnQoNjQgKiAxKSAmIGxvd182NF9tYXNrO1xuICAgIGNvbnN0IHAyID0gdmFsdWUgPj4gQmlnSW50KDY0ICogMikgJiBsb3dfNjRfbWFzaztcbiAgICBjb25zdCBwMyA9IHZhbHVlID4+IEJpZ0ludCg2NCAqIDMpO1xuICAgIHRoaXMudmlldy5zZXRCaWdVaW50NjQodGhpcy5vZmZzZXQgKyA4ICogMCwgcDAsIHRydWUpO1xuICAgIHRoaXMudmlldy5zZXRCaWdVaW50NjQodGhpcy5vZmZzZXQgKyA4ICogMSwgcDEsIHRydWUpO1xuICAgIHRoaXMudmlldy5zZXRCaWdVaW50NjQodGhpcy5vZmZzZXQgKyA4ICogMiwgcDIsIHRydWUpO1xuICAgIHRoaXMudmlldy5zZXRCaWdVaW50NjQodGhpcy5vZmZzZXQgKyA4ICogMywgcDMsIHRydWUpO1xuICAgIHRoaXMub2Zmc2V0ICs9IDMyO1xuICB9XG4gIHdyaXRlSTI1Nih2YWx1ZSkge1xuICAgIHRoaXMuZXhwYW5kQnVmZmVyKDMyKTtcbiAgICBjb25zdCBsb3dfNjRfbWFzayA9IEJpZ0ludChcIjB4RkZGRkZGRkZGRkZGRkZGRlwiKTtcbiAgICBjb25zdCBwMCA9IHZhbHVlICYgbG93XzY0X21hc2s7XG4gICAgY29uc3QgcDEgPSB2YWx1ZSA+PiBCaWdJbnQoNjQgKiAxKSAmIGxvd182NF9tYXNrO1xuICAgIGNvbnN0IHAyID0gdmFsdWUgPj4gQmlnSW50KDY0ICogMikgJiBsb3dfNjRfbWFzaztcbiAgICBjb25zdCBwMyA9IHZhbHVlID4+IEJpZ0ludCg2NCAqIDMpO1xuICAgIHRoaXMudmlldy5zZXRCaWdVaW50NjQodGhpcy5vZmZzZXQgKyA4ICogMCwgcDAsIHRydWUpO1xuICAgIHRoaXMudmlldy5zZXRCaWdVaW50NjQodGhpcy5vZmZzZXQgKyA4ICogMSwgcDEsIHRydWUpO1xuICAgIHRoaXMudmlldy5zZXRCaWdVaW50NjQodGhpcy5vZmZzZXQgKyA4ICogMiwgcDIsIHRydWUpO1xuICAgIHRoaXMudmlldy5zZXRCaWdJbnQ2NCh0aGlzLm9mZnNldCArIDggKiAzLCBwMywgdHJ1ZSk7XG4gICAgdGhpcy5vZmZzZXQgKz0gMzI7XG4gIH1cbiAgd3JpdGVGMzIodmFsdWUpIHtcbiAgICB0aGlzLmV4cGFuZEJ1ZmZlcig0KTtcbiAgICB0aGlzLnZpZXcuc2V0RmxvYXQzMih0aGlzLm9mZnNldCwgdmFsdWUsIHRydWUpO1xuICAgIHRoaXMub2Zmc2V0ICs9IDQ7XG4gIH1cbiAgd3JpdGVGNjQodmFsdWUpIHtcbiAgICB0aGlzLmV4cGFuZEJ1ZmZlcig4KTtcbiAgICB0aGlzLnZpZXcuc2V0RmxvYXQ2NCh0aGlzLm9mZnNldCwgdmFsdWUsIHRydWUpO1xuICAgIHRoaXMub2Zmc2V0ICs9IDg7XG4gIH1cbiAgd3JpdGVTdHJpbmcodmFsdWUpIHtcbiAgICBjb25zdCBlbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKCk7XG4gICAgY29uc3QgZW5jb2RlZFN0cmluZyA9IGVuY29kZXIuZW5jb2RlKHZhbHVlKTtcbiAgICB0aGlzLndyaXRlVUludDhBcnJheShlbmNvZGVkU3RyaW5nKTtcbiAgfVxufTtcblxuLy8gc3JjL2xpYi91dGlsLnRzXG5mdW5jdGlvbiB1aW50OEFycmF5VG9IZXhTdHJpbmcoYXJyYXkpIHtcbiAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5tYXAuY2FsbChhcnJheS5yZXZlcnNlKCksICh4KSA9PiAoXCIwMFwiICsgeC50b1N0cmluZygxNikpLnNsaWNlKC0yKSkuam9pbihcIlwiKTtcbn1cbmZ1bmN0aW9uIHVpbnQ4QXJyYXlUb1UxMjgoYXJyYXkpIHtcbiAgaWYgKGFycmF5Lmxlbmd0aCAhPSAxNikge1xuICAgIHRocm93IG5ldyBFcnJvcihgVWludDhBcnJheSBpcyBub3QgMTYgYnl0ZXMgbG9uZzogJHthcnJheX1gKTtcbiAgfVxuICByZXR1cm4gbmV3IEJpbmFyeVJlYWRlcihhcnJheSkucmVhZFUxMjgoKTtcbn1cbmZ1bmN0aW9uIHVpbnQ4QXJyYXlUb1UyNTYoYXJyYXkpIHtcbiAgaWYgKGFycmF5Lmxlbmd0aCAhPSAzMikge1xuICAgIHRocm93IG5ldyBFcnJvcihgVWludDhBcnJheSBpcyBub3QgMzIgYnl0ZXMgbG9uZzogWyR7YXJyYXl9XWApO1xuICB9XG4gIHJldHVybiBuZXcgQmluYXJ5UmVhZGVyKGFycmF5KS5yZWFkVTI1NigpO1xufVxuZnVuY3Rpb24gaGV4U3RyaW5nVG9VaW50OEFycmF5KHN0cikge1xuICBpZiAoc3RyLnN0YXJ0c1dpdGgoXCIweFwiKSkge1xuICAgIHN0ciA9IHN0ci5zbGljZSgyKTtcbiAgfVxuICBjb25zdCBtYXRjaGVzID0gc3RyLm1hdGNoKC8uezEsMn0vZykgfHwgW107XG4gIGNvbnN0IGRhdGEgPSBVaW50OEFycmF5LmZyb20oXG4gICAgbWF0Y2hlcy5tYXAoKGJ5dGUpID0+IHBhcnNlSW50KGJ5dGUsIDE2KSlcbiAgKTtcbiAgcmV0dXJuIGRhdGEucmV2ZXJzZSgpO1xufVxuZnVuY3Rpb24gaGV4U3RyaW5nVG9VMTI4KHN0cikge1xuICByZXR1cm4gdWludDhBcnJheVRvVTEyOChoZXhTdHJpbmdUb1VpbnQ4QXJyYXkoc3RyKSk7XG59XG5mdW5jdGlvbiBoZXhTdHJpbmdUb1UyNTYoc3RyKSB7XG4gIHJldHVybiB1aW50OEFycmF5VG9VMjU2KGhleFN0cmluZ1RvVWludDhBcnJheShzdHIpKTtcbn1cbmZ1bmN0aW9uIHUxMjhUb1VpbnQ4QXJyYXkoZGF0YSkge1xuICBjb25zdCB3cml0ZXIgPSBuZXcgQmluYXJ5V3JpdGVyKDE2KTtcbiAgd3JpdGVyLndyaXRlVTEyOChkYXRhKTtcbiAgcmV0dXJuIHdyaXRlci5nZXRCdWZmZXIoKTtcbn1cbmZ1bmN0aW9uIHUxMjhUb0hleFN0cmluZyhkYXRhKSB7XG4gIHJldHVybiB1aW50OEFycmF5VG9IZXhTdHJpbmcodTEyOFRvVWludDhBcnJheShkYXRhKSk7XG59XG5mdW5jdGlvbiB1MjU2VG9VaW50OEFycmF5KGRhdGEpIHtcbiAgY29uc3Qgd3JpdGVyID0gbmV3IEJpbmFyeVdyaXRlcigzMik7XG4gIHdyaXRlci53cml0ZVUyNTYoZGF0YSk7XG4gIHJldHVybiB3cml0ZXIuZ2V0QnVmZmVyKCk7XG59XG5mdW5jdGlvbiB1MjU2VG9IZXhTdHJpbmcoZGF0YSkge1xuICByZXR1cm4gdWludDhBcnJheVRvSGV4U3RyaW5nKHUyNTZUb1VpbnQ4QXJyYXkoZGF0YSkpO1xufVxuZnVuY3Rpb24gdG9QYXNjYWxDYXNlKHMpIHtcbiAgY29uc3Qgc3RyID0gdG9DYW1lbENhc2Uocyk7XG4gIHJldHVybiBzdHIuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHIuc2xpY2UoMSk7XG59XG5mdW5jdGlvbiB0b0NhbWVsQ2FzZShzKSB7XG4gIGNvbnN0IHN0ciA9IHMucmVwbGFjZSgvWy1fXSsvZywgXCJfXCIpLnJlcGxhY2UoL18oW2EtekEtWjAtOV0pL2csIChfLCBjKSA9PiBjLnRvVXBwZXJDYXNlKCkpO1xuICByZXR1cm4gc3RyLmNoYXJBdCgwKS50b0xvd2VyQ2FzZSgpICsgc3RyLnNsaWNlKDEpO1xufVxuZnVuY3Rpb24gYnNhdG5CYXNlU2l6ZSh0eXBlc3BhY2UsIHR5KSB7XG4gIGNvbnN0IGFzc3VtZWRBcnJheUxlbmd0aCA9IDQ7XG4gIHdoaWxlICh0eS50YWcgPT09IFwiUmVmXCIpIHR5ID0gdHlwZXNwYWNlLnR5cGVzW3R5LnZhbHVlXTtcbiAgaWYgKHR5LnRhZyA9PT0gXCJQcm9kdWN0XCIpIHtcbiAgICBsZXQgc3VtID0gMDtcbiAgICBmb3IgKGNvbnN0IHsgYWxnZWJyYWljVHlwZTogZWxlbSB9IG9mIHR5LnZhbHVlLmVsZW1lbnRzKSB7XG4gICAgICBzdW0gKz0gYnNhdG5CYXNlU2l6ZSh0eXBlc3BhY2UsIGVsZW0pO1xuICAgIH1cbiAgICByZXR1cm4gc3VtO1xuICB9IGVsc2UgaWYgKHR5LnRhZyA9PT0gXCJTdW1cIikge1xuICAgIGxldCBtaW4gPSBJbmZpbml0eTtcbiAgICBmb3IgKGNvbnN0IHsgYWxnZWJyYWljVHlwZTogdmFyaSB9IG9mIHR5LnZhbHVlLnZhcmlhbnRzKSB7XG4gICAgICBjb25zdCB2U2l6ZSA9IGJzYXRuQmFzZVNpemUodHlwZXNwYWNlLCB2YXJpKTtcbiAgICAgIGlmICh2U2l6ZSA8IG1pbikgbWluID0gdlNpemU7XG4gICAgfVxuICAgIGlmIChtaW4gPT09IEluZmluaXR5KSBtaW4gPSAwO1xuICAgIHJldHVybiA0ICsgbWluO1xuICB9IGVsc2UgaWYgKHR5LnRhZyA9PSBcIkFycmF5XCIpIHtcbiAgICByZXR1cm4gNCArIGFzc3VtZWRBcnJheUxlbmd0aCAqIGJzYXRuQmFzZVNpemUodHlwZXNwYWNlLCB0eS52YWx1ZSk7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBTdHJpbmc6IDQgKyBhc3N1bWVkQXJyYXlMZW5ndGgsXG4gICAgU3VtOiAxLFxuICAgIEJvb2w6IDEsXG4gICAgSTg6IDEsXG4gICAgVTg6IDEsXG4gICAgSTE2OiAyLFxuICAgIFUxNjogMixcbiAgICBJMzI6IDQsXG4gICAgVTMyOiA0LFxuICAgIEYzMjogNCxcbiAgICBJNjQ6IDgsXG4gICAgVTY0OiA4LFxuICAgIEY2NDogOCxcbiAgICBJMTI4OiAxNixcbiAgICBVMTI4OiAxNixcbiAgICBJMjU2OiAzMixcbiAgICBVMjU2OiAzMlxuICB9W3R5LnRhZ107XG59XG52YXIgaGFzT3duID0gT2JqZWN0Lmhhc093bjtcblxuLy8gc3JjL2xpYi9jb25uZWN0aW9uX2lkLnRzXG52YXIgQ29ubmVjdGlvbklkID0gY2xhc3MgX0Nvbm5lY3Rpb25JZCB7XG4gIF9fY29ubmVjdGlvbl9pZF9fO1xuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBgQ29ubmVjdGlvbklkYC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKGRhdGEpIHtcbiAgICB0aGlzLl9fY29ubmVjdGlvbl9pZF9fID0gZGF0YTtcbiAgfVxuICAvKipcbiAgICogR2V0IHRoZSBhbGdlYnJhaWMgdHlwZSByZXByZXNlbnRhdGlvbiBvZiB0aGUge0BsaW5rIENvbm5lY3Rpb25JZH0gdHlwZS5cbiAgICogQHJldHVybnMgVGhlIGFsZ2VicmFpYyB0eXBlIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB0eXBlLlxuICAgKi9cbiAgc3RhdGljIGdldEFsZ2VicmFpY1R5cGUoKSB7XG4gICAgcmV0dXJuIEFsZ2VicmFpY1R5cGUuUHJvZHVjdCh7XG4gICAgICBlbGVtZW50czogW1xuICAgICAgICB7IG5hbWU6IFwiX19jb25uZWN0aW9uX2lkX19cIiwgYWxnZWJyYWljVHlwZTogQWxnZWJyYWljVHlwZS5VMTI4IH1cbiAgICAgIF1cbiAgICB9KTtcbiAgfVxuICBpc1plcm8oKSB7XG4gICAgcmV0dXJuIHRoaXMuX19jb25uZWN0aW9uX2lkX18gPT09IEJpZ0ludCgwKTtcbiAgfVxuICBzdGF0aWMgbnVsbElmWmVybyhhZGRyKSB7XG4gICAgaWYgKGFkZHIuaXNaZXJvKCkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYWRkcjtcbiAgICB9XG4gIH1cbiAgc3RhdGljIHJhbmRvbSgpIHtcbiAgICBmdW5jdGlvbiByYW5kb21VOCgpIHtcbiAgICAgIHJldHVybiBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAyNTUpO1xuICAgIH1cbiAgICBsZXQgcmVzdWx0ID0gQmlnSW50KDApO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMTY7IGkrKykge1xuICAgICAgcmVzdWx0ID0gcmVzdWx0IDw8IEJpZ0ludCg4KSB8IEJpZ0ludChyYW5kb21VOCgpKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBfQ29ubmVjdGlvbklkKHJlc3VsdCk7XG4gIH1cbiAgLyoqXG4gICAqIENvbXBhcmUgdHdvIGNvbm5lY3Rpb24gSURzIGZvciBlcXVhbGl0eS5cbiAgICovXG4gIGlzRXF1YWwob3RoZXIpIHtcbiAgICByZXR1cm4gdGhpcy5fX2Nvbm5lY3Rpb25faWRfXyA9PSBvdGhlci5fX2Nvbm5lY3Rpb25faWRfXztcbiAgfVxuICAvKipcbiAgICogQ2hlY2sgaWYgdHdvIGNvbm5lY3Rpb24gSURzIGFyZSBlcXVhbC5cbiAgICovXG4gIGVxdWFscyhvdGhlcikge1xuICAgIHJldHVybiB0aGlzLmlzRXF1YWwob3RoZXIpO1xuICB9XG4gIC8qKlxuICAgKiBQcmludCB0aGUgY29ubmVjdGlvbiBJRCBhcyBhIGhleGFkZWNpbWFsIHN0cmluZy5cbiAgICovXG4gIHRvSGV4U3RyaW5nKCkge1xuICAgIHJldHVybiB1MTI4VG9IZXhTdHJpbmcodGhpcy5fX2Nvbm5lY3Rpb25faWRfXyk7XG4gIH1cbiAgLyoqXG4gICAqIENvbnZlcnQgdGhlIGNvbm5lY3Rpb24gSUQgdG8gYSBVaW50OEFycmF5LlxuICAgKi9cbiAgdG9VaW50OEFycmF5KCkge1xuICAgIHJldHVybiB1MTI4VG9VaW50OEFycmF5KHRoaXMuX19jb25uZWN0aW9uX2lkX18pO1xuICB9XG4gIC8qKlxuICAgKiBQYXJzZSBhIGNvbm5lY3Rpb24gSUQgZnJvbSBhIGhleGFkZWNpbWFsIHN0cmluZy5cbiAgICovXG4gIHN0YXRpYyBmcm9tU3RyaW5nKHN0cikge1xuICAgIHJldHVybiBuZXcgX0Nvbm5lY3Rpb25JZChoZXhTdHJpbmdUb1UxMjgoc3RyKSk7XG4gIH1cbiAgc3RhdGljIGZyb21TdHJpbmdPck51bGwoc3RyKSB7XG4gICAgY29uc3QgYWRkciA9IF9Db25uZWN0aW9uSWQuZnJvbVN0cmluZyhzdHIpO1xuICAgIGlmIChhZGRyLmlzWmVybygpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGFkZHI7XG4gICAgfVxuICB9XG59O1xuXG4vLyBzcmMvbGliL2lkZW50aXR5LnRzXG52YXIgSWRlbnRpdHkgPSBjbGFzcyBfSWRlbnRpdHkge1xuICBfX2lkZW50aXR5X187XG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IGBJZGVudGl0eWAuXG4gICAqXG4gICAqIGBkYXRhYCBjYW4gYmUgYSBoZXhhZGVjaW1hbCBzdHJpbmcgb3IgYSBgYmlnaW50YC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKGRhdGEpIHtcbiAgICB0aGlzLl9faWRlbnRpdHlfXyA9IHR5cGVvZiBkYXRhID09PSBcInN0cmluZ1wiID8gaGV4U3RyaW5nVG9VMjU2KGRhdGEpIDogZGF0YTtcbiAgfVxuICAvKipcbiAgICogR2V0IHRoZSBhbGdlYnJhaWMgdHlwZSByZXByZXNlbnRhdGlvbiBvZiB0aGUge0BsaW5rIElkZW50aXR5fSB0eXBlLlxuICAgKiBAcmV0dXJucyBUaGUgYWxnZWJyYWljIHR5cGUgcmVwcmVzZW50YXRpb24gb2YgdGhlIHR5cGUuXG4gICAqL1xuICBzdGF0aWMgZ2V0QWxnZWJyYWljVHlwZSgpIHtcbiAgICByZXR1cm4gQWxnZWJyYWljVHlwZS5Qcm9kdWN0KHtcbiAgICAgIGVsZW1lbnRzOiBbeyBuYW1lOiBcIl9faWRlbnRpdHlfX1wiLCBhbGdlYnJhaWNUeXBlOiBBbGdlYnJhaWNUeXBlLlUyNTYgfV1cbiAgICB9KTtcbiAgfVxuICAvKipcbiAgICogQ2hlY2sgaWYgdHdvIGlkZW50aXRpZXMgYXJlIGVxdWFsLlxuICAgKi9cbiAgaXNFcXVhbChvdGhlcikge1xuICAgIHJldHVybiB0aGlzLnRvSGV4U3RyaW5nKCkgPT09IG90aGVyLnRvSGV4U3RyaW5nKCk7XG4gIH1cbiAgLyoqXG4gICAqIENoZWNrIGlmIHR3byBpZGVudGl0aWVzIGFyZSBlcXVhbC5cbiAgICovXG4gIGVxdWFscyhvdGhlcikge1xuICAgIHJldHVybiB0aGlzLmlzRXF1YWwob3RoZXIpO1xuICB9XG4gIC8qKlxuICAgKiBQcmludCB0aGUgaWRlbnRpdHkgYXMgYSBoZXhhZGVjaW1hbCBzdHJpbmcuXG4gICAqL1xuICB0b0hleFN0cmluZygpIHtcbiAgICByZXR1cm4gdTI1NlRvSGV4U3RyaW5nKHRoaXMuX19pZGVudGl0eV9fKTtcbiAgfVxuICAvKipcbiAgICogQ29udmVydCB0aGUgYWRkcmVzcyB0byBhIFVpbnQ4QXJyYXkuXG4gICAqL1xuICB0b1VpbnQ4QXJyYXkoKSB7XG4gICAgcmV0dXJuIHUyNTZUb1VpbnQ4QXJyYXkodGhpcy5fX2lkZW50aXR5X18pO1xuICB9XG4gIC8qKlxuICAgKiBQYXJzZSBhbiBJZGVudGl0eSBmcm9tIGEgaGV4YWRlY2ltYWwgc3RyaW5nLlxuICAgKi9cbiAgc3RhdGljIGZyb21TdHJpbmcoc3RyKSB7XG4gICAgcmV0dXJuIG5ldyBfSWRlbnRpdHkoc3RyKTtcbiAgfVxuICAvKipcbiAgICogWmVybyBpZGVudGl0eSAoMHgwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwKVxuICAgKi9cbiAgc3RhdGljIHplcm8oKSB7XG4gICAgcmV0dXJuIG5ldyBfSWRlbnRpdHkoMG4pO1xuICB9XG4gIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLnRvSGV4U3RyaW5nKCk7XG4gIH1cbn07XG5cbi8vIHNyYy9saWIvYWxnZWJyYWljX3R5cGUudHNcbnZhciBTRVJJQUxJWkVSUyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7XG52YXIgREVTRVJJQUxJWkVSUyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7XG52YXIgQWxnZWJyYWljVHlwZSA9IHtcbiAgUmVmOiAodmFsdWUpID0+ICh7IHRhZzogXCJSZWZcIiwgdmFsdWUgfSksXG4gIFN1bTogKHZhbHVlKSA9PiAoe1xuICAgIHRhZzogXCJTdW1cIixcbiAgICB2YWx1ZVxuICB9KSxcbiAgUHJvZHVjdDogKHZhbHVlKSA9PiAoe1xuICAgIHRhZzogXCJQcm9kdWN0XCIsXG4gICAgdmFsdWVcbiAgfSksXG4gIEFycmF5OiAodmFsdWUpID0+ICh7XG4gICAgdGFnOiBcIkFycmF5XCIsXG4gICAgdmFsdWVcbiAgfSksXG4gIFN0cmluZzogeyB0YWc6IFwiU3RyaW5nXCIgfSxcbiAgQm9vbDogeyB0YWc6IFwiQm9vbFwiIH0sXG4gIEk4OiB7IHRhZzogXCJJOFwiIH0sXG4gIFU4OiB7IHRhZzogXCJVOFwiIH0sXG4gIEkxNjogeyB0YWc6IFwiSTE2XCIgfSxcbiAgVTE2OiB7IHRhZzogXCJVMTZcIiB9LFxuICBJMzI6IHsgdGFnOiBcIkkzMlwiIH0sXG4gIFUzMjogeyB0YWc6IFwiVTMyXCIgfSxcbiAgSTY0OiB7IHRhZzogXCJJNjRcIiB9LFxuICBVNjQ6IHsgdGFnOiBcIlU2NFwiIH0sXG4gIEkxMjg6IHsgdGFnOiBcIkkxMjhcIiB9LFxuICBVMTI4OiB7IHRhZzogXCJVMTI4XCIgfSxcbiAgSTI1NjogeyB0YWc6IFwiSTI1NlwiIH0sXG4gIFUyNTY6IHsgdGFnOiBcIlUyNTZcIiB9LFxuICBGMzI6IHsgdGFnOiBcIkYzMlwiIH0sXG4gIEY2NDogeyB0YWc6IFwiRjY0XCIgfSxcbiAgbWFrZVNlcmlhbGl6ZXIodHksIHR5cGVzcGFjZSkge1xuICAgIGlmICh0eS50YWcgPT09IFwiUmVmXCIpIHtcbiAgICAgIGlmICghdHlwZXNwYWNlKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJjYW5ub3Qgc2VyaWFsaXplIHJlZnMgd2l0aG91dCBhIHR5cGVzcGFjZVwiKTtcbiAgICAgIHdoaWxlICh0eS50YWcgPT09IFwiUmVmXCIpIHR5ID0gdHlwZXNwYWNlLnR5cGVzW3R5LnZhbHVlXTtcbiAgICB9XG4gICAgc3dpdGNoICh0eS50YWcpIHtcbiAgICAgIGNhc2UgXCJQcm9kdWN0XCI6XG4gICAgICAgIHJldHVybiBQcm9kdWN0VHlwZS5tYWtlU2VyaWFsaXplcih0eS52YWx1ZSwgdHlwZXNwYWNlKTtcbiAgICAgIGNhc2UgXCJTdW1cIjpcbiAgICAgICAgcmV0dXJuIFN1bVR5cGUubWFrZVNlcmlhbGl6ZXIodHkudmFsdWUsIHR5cGVzcGFjZSk7XG4gICAgICBjYXNlIFwiQXJyYXlcIjpcbiAgICAgICAgaWYgKHR5LnZhbHVlLnRhZyA9PT0gXCJVOFwiKSB7XG4gICAgICAgICAgcmV0dXJuIHNlcmlhbGl6ZVVpbnQ4QXJyYXk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3Qgc2VyaWFsaXplID0gQWxnZWJyYWljVHlwZS5tYWtlU2VyaWFsaXplcih0eS52YWx1ZSwgdHlwZXNwYWNlKTtcbiAgICAgICAgICByZXR1cm4gKHdyaXRlciwgdmFsdWUpID0+IHtcbiAgICAgICAgICAgIHdyaXRlci53cml0ZVUzMih2YWx1ZS5sZW5ndGgpO1xuICAgICAgICAgICAgZm9yIChjb25zdCBlbGVtIG9mIHZhbHVlKSB7XG4gICAgICAgICAgICAgIHNlcmlhbGl6ZSh3cml0ZXIsIGVsZW0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBwcmltaXRpdmVTZXJpYWxpemVyc1t0eS50YWddO1xuICAgIH1cbiAgfSxcbiAgLyoqIEBkZXByZWNhdGVkIFVzZSBgbWFrZVNlcmlhbGl6ZXJgIGluc3RlYWQuICovXG4gIHNlcmlhbGl6ZVZhbHVlKHdyaXRlciwgdHksIHZhbHVlLCB0eXBlc3BhY2UpIHtcbiAgICBBbGdlYnJhaWNUeXBlLm1ha2VTZXJpYWxpemVyKHR5LCB0eXBlc3BhY2UpKHdyaXRlciwgdmFsdWUpO1xuICB9LFxuICBtYWtlRGVzZXJpYWxpemVyKHR5LCB0eXBlc3BhY2UpIHtcbiAgICBpZiAodHkudGFnID09PSBcIlJlZlwiKSB7XG4gICAgICBpZiAoIXR5cGVzcGFjZSlcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiY2Fubm90IGRlc2VyaWFsaXplIHJlZnMgd2l0aG91dCBhIHR5cGVzcGFjZVwiKTtcbiAgICAgIHdoaWxlICh0eS50YWcgPT09IFwiUmVmXCIpIHR5ID0gdHlwZXNwYWNlLnR5cGVzW3R5LnZhbHVlXTtcbiAgICB9XG4gICAgc3dpdGNoICh0eS50YWcpIHtcbiAgICAgIGNhc2UgXCJQcm9kdWN0XCI6XG4gICAgICAgIHJldHVybiBQcm9kdWN0VHlwZS5tYWtlRGVzZXJpYWxpemVyKHR5LnZhbHVlLCB0eXBlc3BhY2UpO1xuICAgICAgY2FzZSBcIlN1bVwiOlxuICAgICAgICByZXR1cm4gU3VtVHlwZS5tYWtlRGVzZXJpYWxpemVyKHR5LnZhbHVlLCB0eXBlc3BhY2UpO1xuICAgICAgY2FzZSBcIkFycmF5XCI6XG4gICAgICAgIGlmICh0eS52YWx1ZS50YWcgPT09IFwiVThcIikge1xuICAgICAgICAgIHJldHVybiBkZXNlcmlhbGl6ZVVpbnQ4QXJyYXk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgZGVzZXJpYWxpemUgPSBBbGdlYnJhaWNUeXBlLm1ha2VEZXNlcmlhbGl6ZXIoXG4gICAgICAgICAgICB0eS52YWx1ZSxcbiAgICAgICAgICAgIHR5cGVzcGFjZVxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIChyZWFkZXIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGxlbmd0aCA9IHJlYWRlci5yZWFkVTMyKCk7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBBcnJheShsZW5ndGgpO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICByZXN1bHRbaV0gPSBkZXNlcmlhbGl6ZShyZWFkZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gcHJpbWl0aXZlRGVzZXJpYWxpemVyc1t0eS50YWddO1xuICAgIH1cbiAgfSxcbiAgLyoqIEBkZXByZWNhdGVkIFVzZSBgbWFrZURlc2VyaWFsaXplcmAgaW5zdGVhZC4gKi9cbiAgZGVzZXJpYWxpemVWYWx1ZShyZWFkZXIsIHR5LCB0eXBlc3BhY2UpIHtcbiAgICByZXR1cm4gQWxnZWJyYWljVHlwZS5tYWtlRGVzZXJpYWxpemVyKHR5LCB0eXBlc3BhY2UpKHJlYWRlcik7XG4gIH0sXG4gIC8qKlxuICAgKiBDb252ZXJ0IGEgdmFsdWUgb2YgdGhlIGFsZ2VicmFpYyB0eXBlIGludG8gc29tZXRoaW5nIHRoYXQgY2FuIGJlIHVzZWQgYXMgYSBrZXkgaW4gYSBtYXAuXG4gICAqIFRoZXJlIGFyZSBubyBndWFyYW50ZWVzIGFib3V0IGJlaW5nIGFibGUgdG8gb3JkZXIgaXQuXG4gICAqIFRoaXMgaXMgb25seSBndWFyYW50ZWVkIHRvIGJlIGNvbXBhcmFibGUgdG8gb3RoZXIgdmFsdWVzIG9mIHRoZSBzYW1lIHR5cGUuXG4gICAqIEBwYXJhbSB2YWx1ZSBBIHZhbHVlIG9mIHRoZSBhbGdlYnJhaWMgdHlwZVxuICAgKiBAcmV0dXJucyBTb21ldGhpbmcgdGhhdCBjYW4gYmUgdXNlZCBhcyBhIGtleSBpbiBhIG1hcC5cbiAgICovXG4gIGludG9NYXBLZXk6IGZ1bmN0aW9uKHR5LCB2YWx1ZSkge1xuICAgIHN3aXRjaCAodHkudGFnKSB7XG4gICAgICBjYXNlIFwiVThcIjpcbiAgICAgIGNhc2UgXCJVMTZcIjpcbiAgICAgIGNhc2UgXCJVMzJcIjpcbiAgICAgIGNhc2UgXCJVNjRcIjpcbiAgICAgIGNhc2UgXCJVMTI4XCI6XG4gICAgICBjYXNlIFwiVTI1NlwiOlxuICAgICAgY2FzZSBcIkk4XCI6XG4gICAgICBjYXNlIFwiSTE2XCI6XG4gICAgICBjYXNlIFwiSTMyXCI6XG4gICAgICBjYXNlIFwiSTY0XCI6XG4gICAgICBjYXNlIFwiSTEyOFwiOlxuICAgICAgY2FzZSBcIkkyNTZcIjpcbiAgICAgIGNhc2UgXCJGMzJcIjpcbiAgICAgIGNhc2UgXCJGNjRcIjpcbiAgICAgIGNhc2UgXCJTdHJpbmdcIjpcbiAgICAgIGNhc2UgXCJCb29sXCI6XG4gICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgIGNhc2UgXCJQcm9kdWN0XCI6XG4gICAgICAgIHJldHVybiBQcm9kdWN0VHlwZS5pbnRvTWFwS2V5KHR5LnZhbHVlLCB2YWx1ZSk7XG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIGNvbnN0IHdyaXRlciA9IG5ldyBCaW5hcnlXcml0ZXIoMTApO1xuICAgICAgICBBbGdlYnJhaWNUeXBlLnNlcmlhbGl6ZVZhbHVlKHdyaXRlciwgdHksIHZhbHVlKTtcbiAgICAgICAgcmV0dXJuIHdyaXRlci50b0Jhc2U2NCgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufTtcbmZ1bmN0aW9uIGJpbmRDYWxsKGYpIHtcbiAgcmV0dXJuIEZ1bmN0aW9uLnByb3RvdHlwZS5jYWxsLmJpbmQoZik7XG59XG52YXIgcHJpbWl0aXZlU2VyaWFsaXplcnMgPSB7XG4gIEJvb2w6IGJpbmRDYWxsKEJpbmFyeVdyaXRlci5wcm90b3R5cGUud3JpdGVCb29sKSxcbiAgSTg6IGJpbmRDYWxsKEJpbmFyeVdyaXRlci5wcm90b3R5cGUud3JpdGVJOCksXG4gIFU4OiBiaW5kQ2FsbChCaW5hcnlXcml0ZXIucHJvdG90eXBlLndyaXRlVTgpLFxuICBJMTY6IGJpbmRDYWxsKEJpbmFyeVdyaXRlci5wcm90b3R5cGUud3JpdGVJMTYpLFxuICBVMTY6IGJpbmRDYWxsKEJpbmFyeVdyaXRlci5wcm90b3R5cGUud3JpdGVVMTYpLFxuICBJMzI6IGJpbmRDYWxsKEJpbmFyeVdyaXRlci5wcm90b3R5cGUud3JpdGVJMzIpLFxuICBVMzI6IGJpbmRDYWxsKEJpbmFyeVdyaXRlci5wcm90b3R5cGUud3JpdGVVMzIpLFxuICBJNjQ6IGJpbmRDYWxsKEJpbmFyeVdyaXRlci5wcm90b3R5cGUud3JpdGVJNjQpLFxuICBVNjQ6IGJpbmRDYWxsKEJpbmFyeVdyaXRlci5wcm90b3R5cGUud3JpdGVVNjQpLFxuICBJMTI4OiBiaW5kQ2FsbChCaW5hcnlXcml0ZXIucHJvdG90eXBlLndyaXRlSTEyOCksXG4gIFUxMjg6IGJpbmRDYWxsKEJpbmFyeVdyaXRlci5wcm90b3R5cGUud3JpdGVVMTI4KSxcbiAgSTI1NjogYmluZENhbGwoQmluYXJ5V3JpdGVyLnByb3RvdHlwZS53cml0ZUkyNTYpLFxuICBVMjU2OiBiaW5kQ2FsbChCaW5hcnlXcml0ZXIucHJvdG90eXBlLndyaXRlVTI1NiksXG4gIEYzMjogYmluZENhbGwoQmluYXJ5V3JpdGVyLnByb3RvdHlwZS53cml0ZUYzMiksXG4gIEY2NDogYmluZENhbGwoQmluYXJ5V3JpdGVyLnByb3RvdHlwZS53cml0ZUY2NCksXG4gIFN0cmluZzogYmluZENhbGwoQmluYXJ5V3JpdGVyLnByb3RvdHlwZS53cml0ZVN0cmluZylcbn07XG5PYmplY3QuZnJlZXplKHByaW1pdGl2ZVNlcmlhbGl6ZXJzKTtcbnZhciBzZXJpYWxpemVVaW50OEFycmF5ID0gYmluZENhbGwoQmluYXJ5V3JpdGVyLnByb3RvdHlwZS53cml0ZVVJbnQ4QXJyYXkpO1xudmFyIHByaW1pdGl2ZURlc2VyaWFsaXplcnMgPSB7XG4gIEJvb2w6IGJpbmRDYWxsKEJpbmFyeVJlYWRlci5wcm90b3R5cGUucmVhZEJvb2wpLFxuICBJODogYmluZENhbGwoQmluYXJ5UmVhZGVyLnByb3RvdHlwZS5yZWFkSTgpLFxuICBVODogYmluZENhbGwoQmluYXJ5UmVhZGVyLnByb3RvdHlwZS5yZWFkVTgpLFxuICBJMTY6IGJpbmRDYWxsKEJpbmFyeVJlYWRlci5wcm90b3R5cGUucmVhZEkxNiksXG4gIFUxNjogYmluZENhbGwoQmluYXJ5UmVhZGVyLnByb3RvdHlwZS5yZWFkVTE2KSxcbiAgSTMyOiBiaW5kQ2FsbChCaW5hcnlSZWFkZXIucHJvdG90eXBlLnJlYWRJMzIpLFxuICBVMzI6IGJpbmRDYWxsKEJpbmFyeVJlYWRlci5wcm90b3R5cGUucmVhZFUzMiksXG4gIEk2NDogYmluZENhbGwoQmluYXJ5UmVhZGVyLnByb3RvdHlwZS5yZWFkSTY0KSxcbiAgVTY0OiBiaW5kQ2FsbChCaW5hcnlSZWFkZXIucHJvdG90eXBlLnJlYWRVNjQpLFxuICBJMTI4OiBiaW5kQ2FsbChCaW5hcnlSZWFkZXIucHJvdG90eXBlLnJlYWRJMTI4KSxcbiAgVTEyODogYmluZENhbGwoQmluYXJ5UmVhZGVyLnByb3RvdHlwZS5yZWFkVTEyOCksXG4gIEkyNTY6IGJpbmRDYWxsKEJpbmFyeVJlYWRlci5wcm90b3R5cGUucmVhZEkyNTYpLFxuICBVMjU2OiBiaW5kQ2FsbChCaW5hcnlSZWFkZXIucHJvdG90eXBlLnJlYWRVMjU2KSxcbiAgRjMyOiBiaW5kQ2FsbChCaW5hcnlSZWFkZXIucHJvdG90eXBlLnJlYWRGMzIpLFxuICBGNjQ6IGJpbmRDYWxsKEJpbmFyeVJlYWRlci5wcm90b3R5cGUucmVhZEY2NCksXG4gIFN0cmluZzogYmluZENhbGwoQmluYXJ5UmVhZGVyLnByb3RvdHlwZS5yZWFkU3RyaW5nKVxufTtcbk9iamVjdC5mcmVlemUocHJpbWl0aXZlRGVzZXJpYWxpemVycyk7XG52YXIgZGVzZXJpYWxpemVVaW50OEFycmF5ID0gYmluZENhbGwoQmluYXJ5UmVhZGVyLnByb3RvdHlwZS5yZWFkVUludDhBcnJheSk7XG52YXIgcHJpbWl0aXZlU2l6ZXMgPSB7XG4gIEJvb2w6IDEsXG4gIEk4OiAxLFxuICBVODogMSxcbiAgSTE2OiAyLFxuICBVMTY6IDIsXG4gIEkzMjogNCxcbiAgVTMyOiA0LFxuICBJNjQ6IDgsXG4gIFU2NDogOCxcbiAgSTEyODogMTYsXG4gIFUxMjg6IDE2LFxuICBJMjU2OiAzMixcbiAgVTI1NjogMzIsXG4gIEYzMjogNCxcbiAgRjY0OiA4XG59O1xudmFyIGZpeGVkU2l6ZVByaW1pdGl2ZXMgPSBuZXcgU2V0KE9iamVjdC5rZXlzKHByaW1pdGl2ZVNpemVzKSk7XG52YXIgaXNGaXhlZFNpemVQcm9kdWN0ID0gKHR5KSA9PiB0eS5lbGVtZW50cy5ldmVyeShcbiAgKHsgYWxnZWJyYWljVHlwZSB9KSA9PiBmaXhlZFNpemVQcmltaXRpdmVzLmhhcyhhbGdlYnJhaWNUeXBlLnRhZylcbik7XG52YXIgcHJvZHVjdFNpemUgPSAodHkpID0+IHR5LmVsZW1lbnRzLnJlZHVjZShcbiAgKGFjYywgeyBhbGdlYnJhaWNUeXBlIH0pID0+IGFjYyArIHByaW1pdGl2ZVNpemVzW2FsZ2VicmFpY1R5cGUudGFnXSxcbiAgMFxuKTtcbnZhciBwcmltaXRpdmVKU05hbWUgPSB7XG4gIEJvb2w6IFwiVWludDhcIixcbiAgSTg6IFwiSW50OFwiLFxuICBVODogXCJVaW50OFwiLFxuICBJMTY6IFwiSW50MTZcIixcbiAgVTE2OiBcIlVpbnQxNlwiLFxuICBJMzI6IFwiSW50MzJcIixcbiAgVTMyOiBcIlVpbnQzMlwiLFxuICBJNjQ6IFwiQmlnSW50NjRcIixcbiAgVTY0OiBcIkJpZ1VpbnQ2NFwiLFxuICBGMzI6IFwiRmxvYXQzMlwiLFxuICBGNjQ6IFwiRmxvYXQ2NFwiXG59O1xudmFyIHNwZWNpYWxQcm9kdWN0RGVzZXJpYWxpemVycyA9IHtcbiAgX190aW1lX2R1cmF0aW9uX21pY3Jvc19fOiAocmVhZGVyKSA9PiBuZXcgVGltZUR1cmF0aW9uKHJlYWRlci5yZWFkSTY0KCkpLFxuICBfX3RpbWVzdGFtcF9taWNyb3Nfc2luY2VfdW5peF9lcG9jaF9fOiAocmVhZGVyKSA9PiBuZXcgVGltZXN0YW1wKHJlYWRlci5yZWFkSTY0KCkpLFxuICBfX2lkZW50aXR5X186IChyZWFkZXIpID0+IG5ldyBJZGVudGl0eShyZWFkZXIucmVhZFUyNTYoKSksXG4gIF9fY29ubmVjdGlvbl9pZF9fOiAocmVhZGVyKSA9PiBuZXcgQ29ubmVjdGlvbklkKHJlYWRlci5yZWFkVTEyOCgpKSxcbiAgX191dWlkX186IChyZWFkZXIpID0+IG5ldyBVdWlkKHJlYWRlci5yZWFkVTEyOCgpKVxufTtcbk9iamVjdC5mcmVlemUoc3BlY2lhbFByb2R1Y3REZXNlcmlhbGl6ZXJzKTtcbnZhciB1bml0RGVzZXJpYWxpemVyID0gKCkgPT4gKHt9KTtcbnZhciBnZXRFbGVtZW50SW5pdGlhbGl6ZXIgPSAoZWxlbWVudCkgPT4ge1xuICBsZXQgaW5pdDtcbiAgc3dpdGNoIChlbGVtZW50LmFsZ2VicmFpY1R5cGUudGFnKSB7XG4gICAgY2FzZSBcIlN0cmluZ1wiOlxuICAgICAgaW5pdCA9IFwiJydcIjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgXCJCb29sXCI6XG4gICAgICBpbml0ID0gXCJmYWxzZVwiO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBcIkk4XCI6XG4gICAgY2FzZSBcIlU4XCI6XG4gICAgY2FzZSBcIkkxNlwiOlxuICAgIGNhc2UgXCJVMTZcIjpcbiAgICBjYXNlIFwiSTMyXCI6XG4gICAgY2FzZSBcIlUzMlwiOlxuICAgICAgaW5pdCA9IFwiMFwiO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBcIkk2NFwiOlxuICAgIGNhc2UgXCJVNjRcIjpcbiAgICBjYXNlIFwiSTEyOFwiOlxuICAgIGNhc2UgXCJVMTI4XCI6XG4gICAgY2FzZSBcIkkyNTZcIjpcbiAgICBjYXNlIFwiVTI1NlwiOlxuICAgICAgaW5pdCA9IFwiMG5cIjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgXCJGMzJcIjpcbiAgICBjYXNlIFwiRjY0XCI6XG4gICAgICBpbml0ID0gXCIwLjBcIjtcbiAgICAgIGJyZWFrO1xuICAgIGRlZmF1bHQ6XG4gICAgICBpbml0ID0gXCJ1bmRlZmluZWRcIjtcbiAgfVxuICByZXR1cm4gYCR7ZWxlbWVudC5uYW1lfTogJHtpbml0fWA7XG59O1xudmFyIFByb2R1Y3RUeXBlID0ge1xuICBtYWtlU2VyaWFsaXplcih0eSwgdHlwZXNwYWNlKSB7XG4gICAgbGV0IHNlcmlhbGl6ZXIgPSBTRVJJQUxJWkVSUy5nZXQodHkpO1xuICAgIGlmIChzZXJpYWxpemVyICE9IG51bGwpIHJldHVybiBzZXJpYWxpemVyO1xuICAgIGlmIChpc0ZpeGVkU2l6ZVByb2R1Y3QodHkpKSB7XG4gICAgICBjb25zdCBzaXplID0gcHJvZHVjdFNpemUodHkpO1xuICAgICAgY29uc3QgYm9keTIgPSBgXCJ1c2Ugc3RyaWN0XCI7XG53cml0ZXIuZXhwYW5kQnVmZmVyKCR7c2l6ZX0pO1xuY29uc3QgdmlldyA9IHdyaXRlci52aWV3O1xuJHt0eS5lbGVtZW50cy5tYXAoXG4gICAgICAgICh7IG5hbWUsIGFsZ2VicmFpY1R5cGU6IHsgdGFnIH0gfSkgPT4gdGFnIGluIHByaW1pdGl2ZUpTTmFtZSA/IGB2aWV3LnNldCR7cHJpbWl0aXZlSlNOYW1lW3RhZ119KHdyaXRlci5vZmZzZXQsIHZhbHVlLiR7bmFtZX0sICR7cHJpbWl0aXZlU2l6ZXNbdGFnXSA+IDEgPyBcInRydWVcIiA6IFwiXCJ9KTtcbndyaXRlci5vZmZzZXQgKz0gJHtwcmltaXRpdmVTaXplc1t0YWddfTtgIDogYHdyaXRlci53cml0ZSR7dGFnfSh2YWx1ZS4ke25hbWV9KTtgXG4gICAgICApLmpvaW4oXCJcXG5cIil9YDtcbiAgICAgIHNlcmlhbGl6ZXIgPSBGdW5jdGlvbihcIndyaXRlclwiLCBcInZhbHVlXCIsIGJvZHkyKTtcbiAgICAgIFNFUklBTElaRVJTLnNldCh0eSwgc2VyaWFsaXplcik7XG4gICAgICByZXR1cm4gc2VyaWFsaXplcjtcbiAgICB9XG4gICAgY29uc3Qgc2VyaWFsaXplcnMgPSB7fTtcbiAgICBjb25zdCBib2R5ID0gJ1widXNlIHN0cmljdFwiO1xcbicgKyB0eS5lbGVtZW50cy5tYXAoXG4gICAgICAoZWxlbWVudCkgPT4gYHRoaXMuJHtlbGVtZW50Lm5hbWV9KHdyaXRlciwgdmFsdWUuJHtlbGVtZW50Lm5hbWV9KTtgXG4gICAgKS5qb2luKFwiXFxuXCIpO1xuICAgIHNlcmlhbGl6ZXIgPSBGdW5jdGlvbihcIndyaXRlclwiLCBcInZhbHVlXCIsIGJvZHkpLmJpbmQoXG4gICAgICBzZXJpYWxpemVyc1xuICAgICk7XG4gICAgU0VSSUFMSVpFUlMuc2V0KHR5LCBzZXJpYWxpemVyKTtcbiAgICBmb3IgKGNvbnN0IHsgbmFtZSwgYWxnZWJyYWljVHlwZSB9IG9mIHR5LmVsZW1lbnRzKSB7XG4gICAgICBzZXJpYWxpemVyc1tuYW1lXSA9IEFsZ2VicmFpY1R5cGUubWFrZVNlcmlhbGl6ZXIoXG4gICAgICAgIGFsZ2VicmFpY1R5cGUsXG4gICAgICAgIHR5cGVzcGFjZVxuICAgICAgKTtcbiAgICB9XG4gICAgT2JqZWN0LmZyZWV6ZShzZXJpYWxpemVycyk7XG4gICAgcmV0dXJuIHNlcmlhbGl6ZXI7XG4gIH0sXG4gIC8qKiBAZGVwcmVjYXRlZCBVc2UgYG1ha2VTZXJpYWxpemVyYCBpbnN0ZWFkLiAqL1xuICBzZXJpYWxpemVWYWx1ZSh3cml0ZXIsIHR5LCB2YWx1ZSwgdHlwZXNwYWNlKSB7XG4gICAgUHJvZHVjdFR5cGUubWFrZVNlcmlhbGl6ZXIodHksIHR5cGVzcGFjZSkod3JpdGVyLCB2YWx1ZSk7XG4gIH0sXG4gIG1ha2VEZXNlcmlhbGl6ZXIodHksIHR5cGVzcGFjZSkge1xuICAgIHN3aXRjaCAodHkuZWxlbWVudHMubGVuZ3RoKSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIHJldHVybiB1bml0RGVzZXJpYWxpemVyO1xuICAgICAgY2FzZSAxOiB7XG4gICAgICAgIGNvbnN0IGZpZWxkTmFtZSA9IHR5LmVsZW1lbnRzWzBdLm5hbWU7XG4gICAgICAgIGlmIChoYXNPd24oc3BlY2lhbFByb2R1Y3REZXNlcmlhbGl6ZXJzLCBmaWVsZE5hbWUpKVxuICAgICAgICAgIHJldHVybiBzcGVjaWFsUHJvZHVjdERlc2VyaWFsaXplcnNbZmllbGROYW1lXTtcbiAgICAgIH1cbiAgICB9XG4gICAgbGV0IGRlc2VyaWFsaXplciA9IERFU0VSSUFMSVpFUlMuZ2V0KHR5KTtcbiAgICBpZiAoZGVzZXJpYWxpemVyICE9IG51bGwpIHJldHVybiBkZXNlcmlhbGl6ZXI7XG4gICAgaWYgKGlzRml4ZWRTaXplUHJvZHVjdCh0eSkpIHtcbiAgICAgIGNvbnN0IGJvZHkgPSBgXCJ1c2Ugc3RyaWN0XCI7XG5jb25zdCByZXN1bHQgPSB7ICR7dHkuZWxlbWVudHMubWFwKGdldEVsZW1lbnRJbml0aWFsaXplcikuam9pbihcIiwgXCIpfSB9O1xuY29uc3QgdmlldyA9IHJlYWRlci52aWV3O1xuJHt0eS5lbGVtZW50cy5tYXAoXG4gICAgICAgICh7IG5hbWUsIGFsZ2VicmFpY1R5cGU6IHsgdGFnIH0gfSkgPT4gdGFnIGluIHByaW1pdGl2ZUpTTmFtZSA/IHRhZyA9PT0gXCJCb29sXCIgPyBgcmVzdWx0LiR7bmFtZX0gPSB2aWV3LmdldFVpbnQ4KHJlYWRlci5vZmZzZXQpICE9PSAwO1xucmVhZGVyLm9mZnNldCArPSAxO2AgOiBgcmVzdWx0LiR7bmFtZX0gPSB2aWV3LmdldCR7cHJpbWl0aXZlSlNOYW1lW3RhZ119KHJlYWRlci5vZmZzZXQsICR7cHJpbWl0aXZlU2l6ZXNbdGFnXSA+IDEgPyBcInRydWVcIiA6IFwiXCJ9KTtcbnJlYWRlci5vZmZzZXQgKz0gJHtwcmltaXRpdmVTaXplc1t0YWddfTtgIDogYHJlc3VsdC4ke25hbWV9ID0gcmVhZGVyLnJlYWQke3RhZ30oKTtgXG4gICAgICApLmpvaW4oXCJcXG5cIil9XG5yZXR1cm4gcmVzdWx0O2A7XG4gICAgICBkZXNlcmlhbGl6ZXIgPSBGdW5jdGlvbihcInJlYWRlclwiLCBib2R5KTtcbiAgICAgIERFU0VSSUFMSVpFUlMuc2V0KHR5LCBkZXNlcmlhbGl6ZXIpO1xuICAgICAgcmV0dXJuIGRlc2VyaWFsaXplcjtcbiAgICB9XG4gICAgY29uc3QgZGVzZXJpYWxpemVycyA9IHt9O1xuICAgIGRlc2VyaWFsaXplciA9IEZ1bmN0aW9uKFxuICAgICAgXCJyZWFkZXJcIixcbiAgICAgIGBcInVzZSBzdHJpY3RcIjtcbmNvbnN0IHJlc3VsdCA9IHsgJHt0eS5lbGVtZW50cy5tYXAoZ2V0RWxlbWVudEluaXRpYWxpemVyKS5qb2luKFwiLCBcIil9IH07XG4ke3R5LmVsZW1lbnRzLm1hcCgoeyBuYW1lIH0pID0+IGByZXN1bHQuJHtuYW1lfSA9IHRoaXMuJHtuYW1lfShyZWFkZXIpO2ApLmpvaW4oXCJcXG5cIil9XG5yZXR1cm4gcmVzdWx0O2BcbiAgICApLmJpbmQoZGVzZXJpYWxpemVycyk7XG4gICAgREVTRVJJQUxJWkVSUy5zZXQodHksIGRlc2VyaWFsaXplcik7XG4gICAgZm9yIChjb25zdCB7IG5hbWUsIGFsZ2VicmFpY1R5cGUgfSBvZiB0eS5lbGVtZW50cykge1xuICAgICAgZGVzZXJpYWxpemVyc1tuYW1lXSA9IEFsZ2VicmFpY1R5cGUubWFrZURlc2VyaWFsaXplcihcbiAgICAgICAgYWxnZWJyYWljVHlwZSxcbiAgICAgICAgdHlwZXNwYWNlXG4gICAgICApO1xuICAgIH1cbiAgICBPYmplY3QuZnJlZXplKGRlc2VyaWFsaXplcnMpO1xuICAgIHJldHVybiBkZXNlcmlhbGl6ZXI7XG4gIH0sXG4gIC8qKiBAZGVwcmVjYXRlZCBVc2UgYG1ha2VEZXNlcmlhbGl6ZXJgIGluc3RlYWQuICovXG4gIGRlc2VyaWFsaXplVmFsdWUocmVhZGVyLCB0eSwgdHlwZXNwYWNlKSB7XG4gICAgcmV0dXJuIFByb2R1Y3RUeXBlLm1ha2VEZXNlcmlhbGl6ZXIodHksIHR5cGVzcGFjZSkocmVhZGVyKTtcbiAgfSxcbiAgaW50b01hcEtleSh0eSwgdmFsdWUpIHtcbiAgICBpZiAodHkuZWxlbWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgICBjb25zdCBmaWVsZE5hbWUgPSB0eS5lbGVtZW50c1swXS5uYW1lO1xuICAgICAgaWYgKGhhc093bihzcGVjaWFsUHJvZHVjdERlc2VyaWFsaXplcnMsIGZpZWxkTmFtZSkpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlW2ZpZWxkTmFtZV07XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHdyaXRlciA9IG5ldyBCaW5hcnlXcml0ZXIoMTApO1xuICAgIEFsZ2VicmFpY1R5cGUuc2VyaWFsaXplVmFsdWUod3JpdGVyLCBBbGdlYnJhaWNUeXBlLlByb2R1Y3QodHkpLCB2YWx1ZSk7XG4gICAgcmV0dXJuIHdyaXRlci50b0Jhc2U2NCgpO1xuICB9XG59O1xudmFyIFN1bVR5cGUgPSB7XG4gIG1ha2VTZXJpYWxpemVyKHR5LCB0eXBlc3BhY2UpIHtcbiAgICBpZiAodHkudmFyaWFudHMubGVuZ3RoID09IDIgJiYgdHkudmFyaWFudHNbMF0ubmFtZSA9PT0gXCJzb21lXCIgJiYgdHkudmFyaWFudHNbMV0ubmFtZSA9PT0gXCJub25lXCIpIHtcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZSA9IEFsZ2VicmFpY1R5cGUubWFrZVNlcmlhbGl6ZXIoXG4gICAgICAgIHR5LnZhcmlhbnRzWzBdLmFsZ2VicmFpY1R5cGUsXG4gICAgICAgIHR5cGVzcGFjZVxuICAgICAgKTtcbiAgICAgIHJldHVybiAod3JpdGVyLCB2YWx1ZSkgPT4ge1xuICAgICAgICBpZiAodmFsdWUgIT09IG51bGwgJiYgdmFsdWUgIT09IHZvaWQgMCkge1xuICAgICAgICAgIHdyaXRlci53cml0ZUJ5dGUoMCk7XG4gICAgICAgICAgc2VyaWFsaXplKHdyaXRlciwgdmFsdWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHdyaXRlci53cml0ZUJ5dGUoMSk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfSBlbHNlIGlmICh0eS52YXJpYW50cy5sZW5ndGggPT0gMiAmJiB0eS52YXJpYW50c1swXS5uYW1lID09PSBcIm9rXCIgJiYgdHkudmFyaWFudHNbMV0ubmFtZSA9PT0gXCJlcnJcIikge1xuICAgICAgY29uc3Qgc2VyaWFsaXplT2sgPSBBbGdlYnJhaWNUeXBlLm1ha2VTZXJpYWxpemVyKFxuICAgICAgICB0eS52YXJpYW50c1swXS5hbGdlYnJhaWNUeXBlLFxuICAgICAgICB0eXBlc3BhY2VcbiAgICAgICk7XG4gICAgICBjb25zdCBzZXJpYWxpemVFcnIgPSBBbGdlYnJhaWNUeXBlLm1ha2VTZXJpYWxpemVyKFxuICAgICAgICB0eS52YXJpYW50c1swXS5hbGdlYnJhaWNUeXBlLFxuICAgICAgICB0eXBlc3BhY2VcbiAgICAgICk7XG4gICAgICByZXR1cm4gKHdyaXRlciwgdmFsdWUpID0+IHtcbiAgICAgICAgaWYgKFwib2tcIiBpbiB2YWx1ZSkge1xuICAgICAgICAgIHdyaXRlci53cml0ZVU4KDApO1xuICAgICAgICAgIHNlcmlhbGl6ZU9rKHdyaXRlciwgdmFsdWUub2spO1xuICAgICAgICB9IGVsc2UgaWYgKFwiZXJyXCIgaW4gdmFsdWUpIHtcbiAgICAgICAgICB3cml0ZXIud3JpdGVVOCgxKTtcbiAgICAgICAgICBzZXJpYWxpemVFcnIod3JpdGVyLCB2YWx1ZS5lcnIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgICBcImNvdWxkIG5vdCBzZXJpYWxpemUgcmVzdWx0OiBvYmplY3QgaGFkIG5laXRoZXIgYSBgb2tgIG5vciBhbiBgZXJyYCBmaWVsZFwiXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IHNlcmlhbGl6ZXIgPSBTRVJJQUxJWkVSUy5nZXQodHkpO1xuICAgICAgaWYgKHNlcmlhbGl6ZXIgIT0gbnVsbCkgcmV0dXJuIHNlcmlhbGl6ZXI7XG4gICAgICBjb25zdCBzZXJpYWxpemVycyA9IHt9O1xuICAgICAgY29uc3QgYm9keSA9IGBzd2l0Y2ggKHZhbHVlLnRhZykge1xuJHt0eS52YXJpYW50cy5tYXAoXG4gICAgICAgICh7IG5hbWUgfSwgaSkgPT4gYCAgY2FzZSAke0pTT04uc3RyaW5naWZ5KG5hbWUpfTpcbiAgICB3cml0ZXIud3JpdGVCeXRlKCR7aX0pO1xuICAgIHJldHVybiB0aGlzLiR7bmFtZX0od3JpdGVyLCB2YWx1ZS52YWx1ZSk7YFxuICAgICAgKS5qb2luKFwiXFxuXCIpfVxuICBkZWZhdWx0OlxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICBcXGBDb3VsZCBub3Qgc2VyaWFsaXplIHN1bSB0eXBlOyB1bmtub3duIHRhZyBcXCR7dmFsdWUudGFnfVxcYFxuICAgIClcbn1cbmA7XG4gICAgICBzZXJpYWxpemVyID0gRnVuY3Rpb24oXCJ3cml0ZXJcIiwgXCJ2YWx1ZVwiLCBib2R5KS5iaW5kKFxuICAgICAgICBzZXJpYWxpemVyc1xuICAgICAgKTtcbiAgICAgIFNFUklBTElaRVJTLnNldCh0eSwgc2VyaWFsaXplcik7XG4gICAgICBmb3IgKGNvbnN0IHsgbmFtZSwgYWxnZWJyYWljVHlwZSB9IG9mIHR5LnZhcmlhbnRzKSB7XG4gICAgICAgIHNlcmlhbGl6ZXJzW25hbWVdID0gQWxnZWJyYWljVHlwZS5tYWtlU2VyaWFsaXplcihcbiAgICAgICAgICBhbGdlYnJhaWNUeXBlLFxuICAgICAgICAgIHR5cGVzcGFjZVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgT2JqZWN0LmZyZWV6ZShzZXJpYWxpemVycyk7XG4gICAgICByZXR1cm4gc2VyaWFsaXplcjtcbiAgICB9XG4gIH0sXG4gIC8qKiBAZGVwcmVjYXRlZCBVc2UgYG1ha2VTZXJpYWxpemVyYCBpbnN0ZWFkLiAqL1xuICBzZXJpYWxpemVWYWx1ZSh3cml0ZXIsIHR5LCB2YWx1ZSwgdHlwZXNwYWNlKSB7XG4gICAgU3VtVHlwZS5tYWtlU2VyaWFsaXplcih0eSwgdHlwZXNwYWNlKSh3cml0ZXIsIHZhbHVlKTtcbiAgfSxcbiAgbWFrZURlc2VyaWFsaXplcih0eSwgdHlwZXNwYWNlKSB7XG4gICAgaWYgKHR5LnZhcmlhbnRzLmxlbmd0aCA9PSAyICYmIHR5LnZhcmlhbnRzWzBdLm5hbWUgPT09IFwic29tZVwiICYmIHR5LnZhcmlhbnRzWzFdLm5hbWUgPT09IFwibm9uZVwiKSB7XG4gICAgICBjb25zdCBkZXNlcmlhbGl6ZSA9IEFsZ2VicmFpY1R5cGUubWFrZURlc2VyaWFsaXplcihcbiAgICAgICAgdHkudmFyaWFudHNbMF0uYWxnZWJyYWljVHlwZSxcbiAgICAgICAgdHlwZXNwYWNlXG4gICAgICApO1xuICAgICAgcmV0dXJuIChyZWFkZXIpID0+IHtcbiAgICAgICAgY29uc3QgdGFnID0gcmVhZGVyLnJlYWRVOCgpO1xuICAgICAgICBpZiAodGFnID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIGRlc2VyaWFsaXplKHJlYWRlcik7XG4gICAgICAgIH0gZWxzZSBpZiAodGFnID09PSAxKSB7XG4gICAgICAgICAgcmV0dXJuIHZvaWQgMDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBgQ2FuJ3QgZGVzZXJpYWxpemUgYW4gb3B0aW9uIHR5cGUsIGNvdWxkbid0IGZpbmQgJHt0YWd9IHRhZ2A7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfSBlbHNlIGlmICh0eS52YXJpYW50cy5sZW5ndGggPT0gMiAmJiB0eS52YXJpYW50c1swXS5uYW1lID09PSBcIm9rXCIgJiYgdHkudmFyaWFudHNbMV0ubmFtZSA9PT0gXCJlcnJcIikge1xuICAgICAgY29uc3QgZGVzZXJpYWxpemVPayA9IEFsZ2VicmFpY1R5cGUubWFrZURlc2VyaWFsaXplcihcbiAgICAgICAgdHkudmFyaWFudHNbMF0uYWxnZWJyYWljVHlwZSxcbiAgICAgICAgdHlwZXNwYWNlXG4gICAgICApO1xuICAgICAgY29uc3QgZGVzZXJpYWxpemVFcnIgPSBBbGdlYnJhaWNUeXBlLm1ha2VEZXNlcmlhbGl6ZXIoXG4gICAgICAgIHR5LnZhcmlhbnRzWzFdLmFsZ2VicmFpY1R5cGUsXG4gICAgICAgIHR5cGVzcGFjZVxuICAgICAgKTtcbiAgICAgIHJldHVybiAocmVhZGVyKSA9PiB7XG4gICAgICAgIGNvbnN0IHRhZyA9IHJlYWRlci5yZWFkQnl0ZSgpO1xuICAgICAgICBpZiAodGFnID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIHsgb2s6IGRlc2VyaWFsaXplT2socmVhZGVyKSB9O1xuICAgICAgICB9IGVsc2UgaWYgKHRhZyA9PT0gMSkge1xuICAgICAgICAgIHJldHVybiB7IGVycjogZGVzZXJpYWxpemVFcnIocmVhZGVyKSB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IGBDYW4ndCBkZXNlcmlhbGl6ZSBhIHJlc3VsdCB0eXBlLCBjb3VsZG4ndCBmaW5kICR7dGFnfSB0YWdgO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBsZXQgZGVzZXJpYWxpemVyID0gREVTRVJJQUxJWkVSUy5nZXQodHkpO1xuICAgICAgaWYgKGRlc2VyaWFsaXplciAhPSBudWxsKSByZXR1cm4gZGVzZXJpYWxpemVyO1xuICAgICAgY29uc3QgZGVzZXJpYWxpemVycyA9IHt9O1xuICAgICAgZGVzZXJpYWxpemVyID0gRnVuY3Rpb24oXG4gICAgICAgIFwicmVhZGVyXCIsXG4gICAgICAgIGBzd2l0Y2ggKHJlYWRlci5yZWFkVTgoKSkge1xuJHt0eS52YXJpYW50cy5tYXAoXG4gICAgICAgICAgKHsgbmFtZSB9LCBpKSA9PiBgY2FzZSAke2l9OiByZXR1cm4geyB0YWc6ICR7SlNPTi5zdHJpbmdpZnkobmFtZSl9LCB2YWx1ZTogdGhpcy4ke25hbWV9KHJlYWRlcikgfTtgXG4gICAgICAgICkuam9pbihcIlxcblwiKX0gfWBcbiAgICAgICkuYmluZChkZXNlcmlhbGl6ZXJzKTtcbiAgICAgIERFU0VSSUFMSVpFUlMuc2V0KHR5LCBkZXNlcmlhbGl6ZXIpO1xuICAgICAgZm9yIChjb25zdCB7IG5hbWUsIGFsZ2VicmFpY1R5cGUgfSBvZiB0eS52YXJpYW50cykge1xuICAgICAgICBkZXNlcmlhbGl6ZXJzW25hbWVdID0gQWxnZWJyYWljVHlwZS5tYWtlRGVzZXJpYWxpemVyKFxuICAgICAgICAgIGFsZ2VicmFpY1R5cGUsXG4gICAgICAgICAgdHlwZXNwYWNlXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBPYmplY3QuZnJlZXplKGRlc2VyaWFsaXplcnMpO1xuICAgICAgcmV0dXJuIGRlc2VyaWFsaXplcjtcbiAgICB9XG4gIH0sXG4gIC8qKiBAZGVwcmVjYXRlZCBVc2UgYG1ha2VEZXNlcmlhbGl6ZXJgIGluc3RlYWQuICovXG4gIGRlc2VyaWFsaXplVmFsdWUocmVhZGVyLCB0eSwgdHlwZXNwYWNlKSB7XG4gICAgcmV0dXJuIFN1bVR5cGUubWFrZURlc2VyaWFsaXplcih0eSwgdHlwZXNwYWNlKShyZWFkZXIpO1xuICB9XG59O1xuXG4vLyBzcmMvbGliL29wdGlvbi50c1xudmFyIE9wdGlvbiA9IHtcbiAgZ2V0QWxnZWJyYWljVHlwZShpbm5lclR5cGUpIHtcbiAgICByZXR1cm4gQWxnZWJyYWljVHlwZS5TdW0oe1xuICAgICAgdmFyaWFudHM6IFtcbiAgICAgICAgeyBuYW1lOiBcInNvbWVcIiwgYWxnZWJyYWljVHlwZTogaW5uZXJUeXBlIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcIm5vbmVcIixcbiAgICAgICAgICBhbGdlYnJhaWNUeXBlOiBBbGdlYnJhaWNUeXBlLlByb2R1Y3QoeyBlbGVtZW50czogW10gfSlcbiAgICAgICAgfVxuICAgICAgXVxuICAgIH0pO1xuICB9XG59O1xuXG4vLyBzcmMvbGliL3Jlc3VsdC50c1xudmFyIFJlc3VsdCA9IHtcbiAgZ2V0QWxnZWJyYWljVHlwZShva1R5cGUsIGVyclR5cGUpIHtcbiAgICByZXR1cm4gQWxnZWJyYWljVHlwZS5TdW0oe1xuICAgICAgdmFyaWFudHM6IFtcbiAgICAgICAgeyBuYW1lOiBcIm9rXCIsIGFsZ2VicmFpY1R5cGU6IG9rVHlwZSB9LFxuICAgICAgICB7IG5hbWU6IFwiZXJyXCIsIGFsZ2VicmFpY1R5cGU6IGVyclR5cGUgfVxuICAgICAgXVxuICAgIH0pO1xuICB9XG59O1xuXG4vLyBzcmMvbGliL3NjaGVkdWxlX2F0LnRzXG52YXIgU2NoZWR1bGVBdCA9IHtcbiAgaW50ZXJ2YWwodmFsdWUpIHtcbiAgICByZXR1cm4gSW50ZXJ2YWwodmFsdWUpO1xuICB9LFxuICB0aW1lKHZhbHVlKSB7XG4gICAgcmV0dXJuIFRpbWUodmFsdWUpO1xuICB9LFxuICBnZXRBbGdlYnJhaWNUeXBlKCkge1xuICAgIHJldHVybiBBbGdlYnJhaWNUeXBlLlN1bSh7XG4gICAgICB2YXJpYW50czogW1xuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJJbnRlcnZhbFwiLFxuICAgICAgICAgIGFsZ2VicmFpY1R5cGU6IFRpbWVEdXJhdGlvbi5nZXRBbGdlYnJhaWNUeXBlKClcbiAgICAgICAgfSxcbiAgICAgICAgeyBuYW1lOiBcIlRpbWVcIiwgYWxnZWJyYWljVHlwZTogVGltZXN0YW1wLmdldEFsZ2VicmFpY1R5cGUoKSB9XG4gICAgICBdXG4gICAgfSk7XG4gIH0sXG4gIGlzU2NoZWR1bGVBdChhbGdlYnJhaWNUeXBlKSB7XG4gICAgaWYgKGFsZ2VicmFpY1R5cGUudGFnICE9PSBcIlN1bVwiKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IHZhcmlhbnRzID0gYWxnZWJyYWljVHlwZS52YWx1ZS52YXJpYW50cztcbiAgICBpZiAodmFyaWFudHMubGVuZ3RoICE9PSAyKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGludGVydmFsVmFyaWFudCA9IHZhcmlhbnRzLmZpbmQoKHYpID0+IHYubmFtZSA9PT0gXCJJbnRlcnZhbFwiKTtcbiAgICBjb25zdCB0aW1lVmFyaWFudCA9IHZhcmlhbnRzLmZpbmQoKHYpID0+IHYubmFtZSA9PT0gXCJUaW1lXCIpO1xuICAgIGlmICghaW50ZXJ2YWxWYXJpYW50IHx8ICF0aW1lVmFyaWFudCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gVGltZUR1cmF0aW9uLmlzVGltZUR1cmF0aW9uKGludGVydmFsVmFyaWFudC5hbGdlYnJhaWNUeXBlKSAmJiBUaW1lc3RhbXAuaXNUaW1lc3RhbXAodGltZVZhcmlhbnQuYWxnZWJyYWljVHlwZSk7XG4gIH1cbn07XG52YXIgSW50ZXJ2YWwgPSAobWljcm9zKSA9PiAoe1xuICB0YWc6IFwiSW50ZXJ2YWxcIixcbiAgdmFsdWU6IG5ldyBUaW1lRHVyYXRpb24obWljcm9zKVxufSk7XG52YXIgVGltZSA9IChtaWNyb3NTaW5jZVVuaXhFcG9jaCkgPT4gKHtcbiAgdGFnOiBcIlRpbWVcIixcbiAgdmFsdWU6IG5ldyBUaW1lc3RhbXAobWljcm9zU2luY2VVbml4RXBvY2gpXG59KTtcbnZhciBzY2hlZHVsZV9hdF9kZWZhdWx0ID0gU2NoZWR1bGVBdDtcblxuLy8gc3JjL2xpYi90eXBlX3V0aWwudHNcbmZ1bmN0aW9uIHNldCh4LCB0Mikge1xuICByZXR1cm4geyAuLi54LCAuLi50MiB9O1xufVxuXG4vLyBzcmMvbGliL3R5cGVfYnVpbGRlcnMudHNcbnZhciBUeXBlQnVpbGRlciA9IGNsYXNzIHtcbiAgLyoqXG4gICAqIFRoZSBUeXBlU2NyaXB0IHBoYW50b20gdHlwZS4gVGhpcyBpcyBub3Qgc3RvcmVkIGF0IHJ1bnRpbWUsXG4gICAqIGJ1dCBpcyB2aXNpYmxlIHRvIHRoZSBjb21waWxlclxuICAgKi9cbiAgdHlwZTtcbiAgLyoqXG4gICAqIFRoZSBTcGFjZXRpbWVEQiBhbGdlYnJhaWMgdHlwZSAocnVu4oCRdGltZSB2YWx1ZSkuIEluIGFkZGl0aW9uIHRvIHN0b3JpbmdcbiAgICogdGhlIHJ1bnRpbWUgcmVwcmVzZW50YXRpb24gb2YgdGhlIGBBbGdlYnJhaWNUeXBlYCwgaXQgYWxzbyBjYXB0dXJlc1xuICAgKiB0aGUgVHlwZVNjcmlwdCB0eXBlIGluZm9ybWF0aW9uIG9mIHRoZSBgQWxnZWJyYWljVHlwZWAuIFRoYXQgaXMgdG8gc2F5XG4gICAqIHRoZSB2YWx1ZSBpcyBub3QgbWVyZWx5IGFuIGBBbGdlYnJhaWNUeXBlYCwgYnV0IGlzIGNvbnN0cnVjdGVkIHRvIGJlXG4gICAqIHRoZSBjb3JyZXNwb25kaW5nIGNvbmNyZXRlIGBBbGdlYnJhaWNUeXBlYCBmb3IgdGhlIFR5cGVTY3JpcHQgdHlwZSBgVHlwZWAuXG4gICAqXG4gICAqIGUuZy4gYHN0cmluZ2AgY29ycmVzcG9uZHMgdG8gYEFsZ2VicmFpY1R5cGUuU3RyaW5nYFxuICAgKi9cbiAgYWxnZWJyYWljVHlwZTtcbiAgY29uc3RydWN0b3IoYWxnZWJyYWljVHlwZSkge1xuICAgIHRoaXMuYWxnZWJyYWljVHlwZSA9IGFsZ2VicmFpY1R5cGU7XG4gIH1cbiAgb3B0aW9uYWwoKSB7XG4gICAgcmV0dXJuIG5ldyBPcHRpb25CdWlsZGVyKHRoaXMpO1xuICB9XG4gIHNlcmlhbGl6ZSh3cml0ZXIsIHZhbHVlKSB7XG4gICAgY29uc3Qgc2VyaWFsaXplID0gdGhpcy5zZXJpYWxpemUgPSBBbGdlYnJhaWNUeXBlLm1ha2VTZXJpYWxpemVyKFxuICAgICAgdGhpcy5hbGdlYnJhaWNUeXBlXG4gICAgKTtcbiAgICBzZXJpYWxpemUod3JpdGVyLCB2YWx1ZSk7XG4gIH1cbiAgZGVzZXJpYWxpemUocmVhZGVyKSB7XG4gICAgY29uc3QgZGVzZXJpYWxpemUgPSB0aGlzLmRlc2VyaWFsaXplID0gQWxnZWJyYWljVHlwZS5tYWtlRGVzZXJpYWxpemVyKFxuICAgICAgdGhpcy5hbGdlYnJhaWNUeXBlXG4gICAgKTtcbiAgICByZXR1cm4gZGVzZXJpYWxpemUocmVhZGVyKTtcbiAgfVxufTtcbnZhciBVOEJ1aWxkZXIgPSBjbGFzcyBleHRlbmRzIFR5cGVCdWlsZGVyIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoQWxnZWJyYWljVHlwZS5VOCk7XG4gIH1cbiAgaW5kZXgoYWxnb3JpdGhtID0gXCJidHJlZVwiKSB7XG4gICAgcmV0dXJuIG5ldyBVOENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgdW5pcXVlKCkge1xuICAgIHJldHVybiBuZXcgVThDb2x1bW5CdWlsZGVyKHRoaXMsIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaXNVbmlxdWU6IHRydWUgfSkpO1xuICB9XG4gIHByaW1hcnlLZXkoKSB7XG4gICAgcmV0dXJuIG5ldyBVOENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc1ByaW1hcnlLZXk6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGF1dG9JbmMoKSB7XG4gICAgcmV0dXJuIG5ldyBVOENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc0F1dG9JbmNyZW1lbnQ6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IFU4Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGRlZmF1bHRWYWx1ZTogdmFsdWUgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgVThDb2x1bW5CdWlsZGVyKHRoaXMsIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgbmFtZSB9KSk7XG4gIH1cbn07XG52YXIgVTE2QnVpbGRlciA9IGNsYXNzIGV4dGVuZHMgVHlwZUJ1aWxkZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihBbGdlYnJhaWNUeXBlLlUxNik7XG4gIH1cbiAgaW5kZXgoYWxnb3JpdGhtID0gXCJidHJlZVwiKSB7XG4gICAgcmV0dXJuIG5ldyBVMTZDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaW5kZXhUeXBlOiBhbGdvcml0aG0gfSlcbiAgICApO1xuICB9XG4gIHVuaXF1ZSgpIHtcbiAgICByZXR1cm4gbmV3IFUxNkNvbHVtbkJ1aWxkZXIodGhpcywgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc1VuaXF1ZTogdHJ1ZSB9KSk7XG4gIH1cbiAgcHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gbmV3IFUxNkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc1ByaW1hcnlLZXk6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGF1dG9JbmMoKSB7XG4gICAgcmV0dXJuIG5ldyBVMTZDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaXNBdXRvSW5jcmVtZW50OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBVMTZDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgZGVmYXVsdFZhbHVlOiB2YWx1ZSB9KVxuICAgICk7XG4gIH1cbiAgbmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBVMTZDb2x1bW5CdWlsZGVyKHRoaXMsIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgbmFtZSB9KSk7XG4gIH1cbn07XG52YXIgVTMyQnVpbGRlciA9IGNsYXNzIGV4dGVuZHMgVHlwZUJ1aWxkZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihBbGdlYnJhaWNUeXBlLlUzMik7XG4gIH1cbiAgaW5kZXgoYWxnb3JpdGhtID0gXCJidHJlZVwiKSB7XG4gICAgcmV0dXJuIG5ldyBVMzJDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaW5kZXhUeXBlOiBhbGdvcml0aG0gfSlcbiAgICApO1xuICB9XG4gIHVuaXF1ZSgpIHtcbiAgICByZXR1cm4gbmV3IFUzMkNvbHVtbkJ1aWxkZXIodGhpcywgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc1VuaXF1ZTogdHJ1ZSB9KSk7XG4gIH1cbiAgcHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gbmV3IFUzMkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc1ByaW1hcnlLZXk6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGF1dG9JbmMoKSB7XG4gICAgcmV0dXJuIG5ldyBVMzJDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaXNBdXRvSW5jcmVtZW50OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBVMzJDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgZGVmYXVsdFZhbHVlOiB2YWx1ZSB9KVxuICAgICk7XG4gIH1cbiAgbmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBVMzJDb2x1bW5CdWlsZGVyKHRoaXMsIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgbmFtZSB9KSk7XG4gIH1cbn07XG52YXIgVTY0QnVpbGRlciA9IGNsYXNzIGV4dGVuZHMgVHlwZUJ1aWxkZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihBbGdlYnJhaWNUeXBlLlU2NCk7XG4gIH1cbiAgaW5kZXgoYWxnb3JpdGhtID0gXCJidHJlZVwiKSB7XG4gICAgcmV0dXJuIG5ldyBVNjRDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaW5kZXhUeXBlOiBhbGdvcml0aG0gfSlcbiAgICApO1xuICB9XG4gIHVuaXF1ZSgpIHtcbiAgICByZXR1cm4gbmV3IFU2NENvbHVtbkJ1aWxkZXIodGhpcywgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc1VuaXF1ZTogdHJ1ZSB9KSk7XG4gIH1cbiAgcHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gbmV3IFU2NENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc1ByaW1hcnlLZXk6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGF1dG9JbmMoKSB7XG4gICAgcmV0dXJuIG5ldyBVNjRDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaXNBdXRvSW5jcmVtZW50OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBVNjRDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgZGVmYXVsdFZhbHVlOiB2YWx1ZSB9KVxuICAgICk7XG4gIH1cbiAgbmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBVNjRDb2x1bW5CdWlsZGVyKHRoaXMsIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgbmFtZSB9KSk7XG4gIH1cbn07XG52YXIgVTEyOEJ1aWxkZXIgPSBjbGFzcyBleHRlbmRzIFR5cGVCdWlsZGVyIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoQWxnZWJyYWljVHlwZS5VMTI4KTtcbiAgfVxuICBpbmRleChhbGdvcml0aG0gPSBcImJ0cmVlXCIpIHtcbiAgICByZXR1cm4gbmV3IFUxMjhDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaW5kZXhUeXBlOiBhbGdvcml0aG0gfSlcbiAgICApO1xuICB9XG4gIHVuaXF1ZSgpIHtcbiAgICByZXR1cm4gbmV3IFUxMjhDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaXNVbmlxdWU6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIHByaW1hcnlLZXkoKSB7XG4gICAgcmV0dXJuIG5ldyBVMTI4Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGlzUHJpbWFyeUtleTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgYXV0b0luYygpIHtcbiAgICByZXR1cm4gbmV3IFUxMjhDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaXNBdXRvSW5jcmVtZW50OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBVMTI4Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGRlZmF1bHRWYWx1ZTogdmFsdWUgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgVTEyOENvbHVtbkJ1aWxkZXIodGhpcywgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBuYW1lIH0pKTtcbiAgfVxufTtcbnZhciBVMjU2QnVpbGRlciA9IGNsYXNzIGV4dGVuZHMgVHlwZUJ1aWxkZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihBbGdlYnJhaWNUeXBlLlUyNTYpO1xuICB9XG4gIGluZGV4KGFsZ29yaXRobSA9IFwiYnRyZWVcIikge1xuICAgIHJldHVybiBuZXcgVTI1NkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgdW5pcXVlKCkge1xuICAgIHJldHVybiBuZXcgVTI1NkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc1VuaXF1ZTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgcHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gbmV3IFUyNTZDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaXNQcmltYXJ5S2V5OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBhdXRvSW5jKCkge1xuICAgIHJldHVybiBuZXcgVTI1NkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc0F1dG9JbmNyZW1lbnQ6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IFUyNTZDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgZGVmYXVsdFZhbHVlOiB2YWx1ZSB9KVxuICAgICk7XG4gIH1cbiAgbmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBVMjU2Q29sdW1uQnVpbGRlcih0aGlzLCBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IG5hbWUgfSkpO1xuICB9XG59O1xudmFyIEk4QnVpbGRlciA9IGNsYXNzIGV4dGVuZHMgVHlwZUJ1aWxkZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihBbGdlYnJhaWNUeXBlLkk4KTtcbiAgfVxuICBpbmRleChhbGdvcml0aG0gPSBcImJ0cmVlXCIpIHtcbiAgICByZXR1cm4gbmV3IEk4Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGluZGV4VHlwZTogYWxnb3JpdGhtIH0pXG4gICAgKTtcbiAgfVxuICB1bmlxdWUoKSB7XG4gICAgcmV0dXJuIG5ldyBJOENvbHVtbkJ1aWxkZXIodGhpcywgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc1VuaXF1ZTogdHJ1ZSB9KSk7XG4gIH1cbiAgcHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gbmV3IEk4Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGlzUHJpbWFyeUtleTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgYXV0b0luYygpIHtcbiAgICByZXR1cm4gbmV3IEk4Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGlzQXV0b0luY3JlbWVudDogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgZGVmYXVsdCh2YWx1ZSkge1xuICAgIHJldHVybiBuZXcgSThDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgZGVmYXVsdFZhbHVlOiB2YWx1ZSB9KVxuICAgICk7XG4gIH1cbiAgbmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBJOENvbHVtbkJ1aWxkZXIodGhpcywgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBuYW1lIH0pKTtcbiAgfVxufTtcbnZhciBJMTZCdWlsZGVyID0gY2xhc3MgZXh0ZW5kcyBUeXBlQnVpbGRlciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKEFsZ2VicmFpY1R5cGUuSTE2KTtcbiAgfVxuICBpbmRleChhbGdvcml0aG0gPSBcImJ0cmVlXCIpIHtcbiAgICByZXR1cm4gbmV3IEkxNkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgdW5pcXVlKCkge1xuICAgIHJldHVybiBuZXcgSTE2Q29sdW1uQnVpbGRlcih0aGlzLCBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGlzVW5pcXVlOiB0cnVlIH0pKTtcbiAgfVxuICBwcmltYXJ5S2V5KCkge1xuICAgIHJldHVybiBuZXcgSTE2Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGlzUHJpbWFyeUtleTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgYXV0b0luYygpIHtcbiAgICByZXR1cm4gbmV3IEkxNkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc0F1dG9JbmNyZW1lbnQ6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IEkxNkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBkZWZhdWx0VmFsdWU6IHZhbHVlIH0pXG4gICAgKTtcbiAgfVxuICBuYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IEkxNkNvbHVtbkJ1aWxkZXIodGhpcywgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBuYW1lIH0pKTtcbiAgfVxufTtcbnZhciBJMzJCdWlsZGVyID0gY2xhc3MgZXh0ZW5kcyBUeXBlQnVpbGRlciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKEFsZ2VicmFpY1R5cGUuSTMyKTtcbiAgfVxuICBpbmRleChhbGdvcml0aG0gPSBcImJ0cmVlXCIpIHtcbiAgICByZXR1cm4gbmV3IEkzMkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgdW5pcXVlKCkge1xuICAgIHJldHVybiBuZXcgSTMyQ29sdW1uQnVpbGRlcih0aGlzLCBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGlzVW5pcXVlOiB0cnVlIH0pKTtcbiAgfVxuICBwcmltYXJ5S2V5KCkge1xuICAgIHJldHVybiBuZXcgSTMyQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGlzUHJpbWFyeUtleTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgYXV0b0luYygpIHtcbiAgICByZXR1cm4gbmV3IEkzMkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc0F1dG9JbmNyZW1lbnQ6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IEkzMkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBkZWZhdWx0VmFsdWU6IHZhbHVlIH0pXG4gICAgKTtcbiAgfVxuICBuYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IEkzMkNvbHVtbkJ1aWxkZXIodGhpcywgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBuYW1lIH0pKTtcbiAgfVxufTtcbnZhciBJNjRCdWlsZGVyID0gY2xhc3MgZXh0ZW5kcyBUeXBlQnVpbGRlciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKEFsZ2VicmFpY1R5cGUuSTY0KTtcbiAgfVxuICBpbmRleChhbGdvcml0aG0gPSBcImJ0cmVlXCIpIHtcbiAgICByZXR1cm4gbmV3IEk2NENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgdW5pcXVlKCkge1xuICAgIHJldHVybiBuZXcgSTY0Q29sdW1uQnVpbGRlcih0aGlzLCBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGlzVW5pcXVlOiB0cnVlIH0pKTtcbiAgfVxuICBwcmltYXJ5S2V5KCkge1xuICAgIHJldHVybiBuZXcgSTY0Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGlzUHJpbWFyeUtleTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgYXV0b0luYygpIHtcbiAgICByZXR1cm4gbmV3IEk2NENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc0F1dG9JbmNyZW1lbnQ6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IEk2NENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBkZWZhdWx0VmFsdWU6IHZhbHVlIH0pXG4gICAgKTtcbiAgfVxuICBuYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IEk2NENvbHVtbkJ1aWxkZXIodGhpcywgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBuYW1lIH0pKTtcbiAgfVxufTtcbnZhciBJMTI4QnVpbGRlciA9IGNsYXNzIGV4dGVuZHMgVHlwZUJ1aWxkZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihBbGdlYnJhaWNUeXBlLkkxMjgpO1xuICB9XG4gIGluZGV4KGFsZ29yaXRobSA9IFwiYnRyZWVcIikge1xuICAgIHJldHVybiBuZXcgSTEyOENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgdW5pcXVlKCkge1xuICAgIHJldHVybiBuZXcgSTEyOENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc1VuaXF1ZTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgcHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gbmV3IEkxMjhDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaXNQcmltYXJ5S2V5OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBhdXRvSW5jKCkge1xuICAgIHJldHVybiBuZXcgSTEyOENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc0F1dG9JbmNyZW1lbnQ6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IEkxMjhDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgZGVmYXVsdFZhbHVlOiB2YWx1ZSB9KVxuICAgICk7XG4gIH1cbiAgbmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBJMTI4Q29sdW1uQnVpbGRlcih0aGlzLCBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IG5hbWUgfSkpO1xuICB9XG59O1xudmFyIEkyNTZCdWlsZGVyID0gY2xhc3MgZXh0ZW5kcyBUeXBlQnVpbGRlciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKEFsZ2VicmFpY1R5cGUuSTI1Nik7XG4gIH1cbiAgaW5kZXgoYWxnb3JpdGhtID0gXCJidHJlZVwiKSB7XG4gICAgcmV0dXJuIG5ldyBJMjU2Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGluZGV4VHlwZTogYWxnb3JpdGhtIH0pXG4gICAgKTtcbiAgfVxuICB1bmlxdWUoKSB7XG4gICAgcmV0dXJuIG5ldyBJMjU2Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGlzVW5pcXVlOiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBwcmltYXJ5S2V5KCkge1xuICAgIHJldHVybiBuZXcgSTI1NkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc1ByaW1hcnlLZXk6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGF1dG9JbmMoKSB7XG4gICAgcmV0dXJuIG5ldyBJMjU2Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGlzQXV0b0luY3JlbWVudDogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgZGVmYXVsdCh2YWx1ZSkge1xuICAgIHJldHVybiBuZXcgSTI1NkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBkZWZhdWx0VmFsdWU6IHZhbHVlIH0pXG4gICAgKTtcbiAgfVxuICBuYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IEkyNTZDb2x1bW5CdWlsZGVyKHRoaXMsIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgbmFtZSB9KSk7XG4gIH1cbn07XG52YXIgRjMyQnVpbGRlciA9IGNsYXNzIGV4dGVuZHMgVHlwZUJ1aWxkZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihBbGdlYnJhaWNUeXBlLkYzMik7XG4gIH1cbiAgZGVmYXVsdCh2YWx1ZSkge1xuICAgIHJldHVybiBuZXcgRjMyQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGRlZmF1bHRWYWx1ZTogdmFsdWUgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgRjMyQ29sdW1uQnVpbGRlcih0aGlzLCBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IG5hbWUgfSkpO1xuICB9XG59O1xudmFyIEY2NEJ1aWxkZXIgPSBjbGFzcyBleHRlbmRzIFR5cGVCdWlsZGVyIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoQWxnZWJyYWljVHlwZS5GNjQpO1xuICB9XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IEY2NENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBkZWZhdWx0VmFsdWU6IHZhbHVlIH0pXG4gICAgKTtcbiAgfVxuICBuYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IEY2NENvbHVtbkJ1aWxkZXIodGhpcywgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBuYW1lIH0pKTtcbiAgfVxufTtcbnZhciBCb29sQnVpbGRlciA9IGNsYXNzIGV4dGVuZHMgVHlwZUJ1aWxkZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihBbGdlYnJhaWNUeXBlLkJvb2wpO1xuICB9XG4gIGluZGV4KGFsZ29yaXRobSA9IFwiYnRyZWVcIikge1xuICAgIHJldHVybiBuZXcgQm9vbENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgdW5pcXVlKCkge1xuICAgIHJldHVybiBuZXcgQm9vbENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc1VuaXF1ZTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgcHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gbmV3IEJvb2xDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaXNQcmltYXJ5S2V5OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBCb29sQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGRlZmF1bHRWYWx1ZTogdmFsdWUgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgQm9vbENvbHVtbkJ1aWxkZXIodGhpcywgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBuYW1lIH0pKTtcbiAgfVxufTtcbnZhciBTdHJpbmdCdWlsZGVyID0gY2xhc3MgZXh0ZW5kcyBUeXBlQnVpbGRlciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKEFsZ2VicmFpY1R5cGUuU3RyaW5nKTtcbiAgfVxuICBpbmRleChhbGdvcml0aG0gPSBcImJ0cmVlXCIpIHtcbiAgICByZXR1cm4gbmV3IFN0cmluZ0NvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgdW5pcXVlKCkge1xuICAgIHJldHVybiBuZXcgU3RyaW5nQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGlzVW5pcXVlOiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBwcmltYXJ5S2V5KCkge1xuICAgIHJldHVybiBuZXcgU3RyaW5nQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGlzUHJpbWFyeUtleTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgZGVmYXVsdCh2YWx1ZSkge1xuICAgIHJldHVybiBuZXcgU3RyaW5nQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGRlZmF1bHRWYWx1ZTogdmFsdWUgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgU3RyaW5nQ29sdW1uQnVpbGRlcih0aGlzLCBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IG5hbWUgfSkpO1xuICB9XG59O1xudmFyIEFycmF5QnVpbGRlciA9IGNsYXNzIGV4dGVuZHMgVHlwZUJ1aWxkZXIge1xuICBlbGVtZW50O1xuICBjb25zdHJ1Y3RvcihlbGVtZW50KSB7XG4gICAgc3VwZXIoQWxnZWJyYWljVHlwZS5BcnJheShlbGVtZW50LmFsZ2VicmFpY1R5cGUpKTtcbiAgICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuICB9XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IEFycmF5Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGRlZmF1bHRWYWx1ZTogdmFsdWUgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgQXJyYXlDb2x1bW5CdWlsZGVyKHRoaXMsIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgbmFtZSB9KSk7XG4gIH1cbn07XG52YXIgQnl0ZUFycmF5QnVpbGRlciA9IGNsYXNzIGV4dGVuZHMgVHlwZUJ1aWxkZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihBbGdlYnJhaWNUeXBlLkFycmF5KEFsZ2VicmFpY1R5cGUuVTgpKTtcbiAgfVxuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBCeXRlQXJyYXlDb2x1bW5CdWlsZGVyKFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBkZWZhdWx0VmFsdWU6IHZhbHVlIH0pXG4gICAgKTtcbiAgfVxuICBuYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IEJ5dGVBcnJheUNvbHVtbkJ1aWxkZXIoc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBuYW1lIH0pKTtcbiAgfVxufTtcbnZhciBPcHRpb25CdWlsZGVyID0gY2xhc3MgZXh0ZW5kcyBUeXBlQnVpbGRlciB7XG4gIHZhbHVlO1xuICBjb25zdHJ1Y3Rvcih2YWx1ZSkge1xuICAgIHN1cGVyKE9wdGlvbi5nZXRBbGdlYnJhaWNUeXBlKHZhbHVlLmFsZ2VicmFpY1R5cGUpKTtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gIH1cbiAgZGVmYXVsdCh2YWx1ZSkge1xuICAgIHJldHVybiBuZXcgT3B0aW9uQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGRlZmF1bHRWYWx1ZTogdmFsdWUgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgT3B0aW9uQ29sdW1uQnVpbGRlcih0aGlzLCBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IG5hbWUgfSkpO1xuICB9XG59O1xudmFyIFByb2R1Y3RCdWlsZGVyID0gY2xhc3MgZXh0ZW5kcyBUeXBlQnVpbGRlciB7XG4gIHR5cGVOYW1lO1xuICBlbGVtZW50cztcbiAgY29uc3RydWN0b3IoZWxlbWVudHMsIG5hbWUpIHtcbiAgICBmdW5jdGlvbiBlbGVtZW50c0FycmF5RnJvbUVsZW1lbnRzT2JqKG9iaikge1xuICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKG9iaikubWFwKChrZXkpID0+ICh7XG4gICAgICAgIG5hbWU6IGtleSxcbiAgICAgICAgLy8gTGF6aWx5IHJlc29sdmUgdGhlIHVuZGVybHlpbmcgb2JqZWN0J3MgYWxnZWJyYWljVHlwZS5cbiAgICAgICAgLy8gVGhpcyB3aWxsIGNhbGwgb2JqW2tleV0uYWxnZWJyYWljVHlwZSBvbmx5IHdoZW4gc29tZW9uZVxuICAgICAgICAvLyBhY3R1YWxseSByZWFkcyB0aGlzIHByb3BlcnR5LlxuICAgICAgICBnZXQgYWxnZWJyYWljVHlwZSgpIHtcbiAgICAgICAgICByZXR1cm4gb2JqW2tleV0uYWxnZWJyYWljVHlwZTtcbiAgICAgICAgfVxuICAgICAgfSkpO1xuICAgIH1cbiAgICBzdXBlcihcbiAgICAgIEFsZ2VicmFpY1R5cGUuUHJvZHVjdCh7XG4gICAgICAgIGVsZW1lbnRzOiBlbGVtZW50c0FycmF5RnJvbUVsZW1lbnRzT2JqKGVsZW1lbnRzKVxuICAgICAgfSlcbiAgICApO1xuICAgIHRoaXMudHlwZU5hbWUgPSBuYW1lO1xuICAgIHRoaXMuZWxlbWVudHMgPSBlbGVtZW50cztcbiAgfVxuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9kdWN0Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGRlZmF1bHRWYWx1ZTogdmFsdWUgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgUHJvZHVjdENvbHVtbkJ1aWxkZXIodGhpcywgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBuYW1lIH0pKTtcbiAgfVxufTtcbnZhciBSZXN1bHRCdWlsZGVyID0gY2xhc3MgZXh0ZW5kcyBUeXBlQnVpbGRlciB7XG4gIG9rO1xuICBlcnI7XG4gIGNvbnN0cnVjdG9yKG9rLCBlcnIpIHtcbiAgICBzdXBlcihSZXN1bHQuZ2V0QWxnZWJyYWljVHlwZShvay5hbGdlYnJhaWNUeXBlLCBlcnIuYWxnZWJyYWljVHlwZSkpO1xuICAgIHRoaXMub2sgPSBvaztcbiAgICB0aGlzLmVyciA9IGVycjtcbiAgfVxuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBSZXN1bHRDb2x1bW5CdWlsZGVyKHRoaXMsIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgZGVmYXVsdFZhbHVlOiB2YWx1ZSB9KSk7XG4gIH1cbn07XG52YXIgVW5pdEJ1aWxkZXIgPSBjbGFzcyBleHRlbmRzIFR5cGVCdWlsZGVyIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoeyB0YWc6IFwiUHJvZHVjdFwiLCB2YWx1ZTogeyBlbGVtZW50czogW10gfSB9KTtcbiAgfVxufTtcbnZhciBSb3dCdWlsZGVyID0gY2xhc3MgZXh0ZW5kcyBUeXBlQnVpbGRlciB7XG4gIHJvdztcbiAgdHlwZU5hbWU7XG4gIGNvbnN0cnVjdG9yKHJvdywgbmFtZSkge1xuICAgIGNvbnN0IG1hcHBlZFJvdyA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgIE9iamVjdC5lbnRyaWVzKHJvdykubWFwKChbY29sTmFtZSwgYnVpbGRlcl0pID0+IFtcbiAgICAgICAgY29sTmFtZSxcbiAgICAgICAgYnVpbGRlciBpbnN0YW5jZW9mIENvbHVtbkJ1aWxkZXIgPyBidWlsZGVyIDogbmV3IENvbHVtbkJ1aWxkZXIoYnVpbGRlciwge30pXG4gICAgICBdKVxuICAgICk7XG4gICAgY29uc3QgZWxlbWVudHMgPSBPYmplY3Qua2V5cyhtYXBwZWRSb3cpLm1hcCgobmFtZTIpID0+ICh7XG4gICAgICBuYW1lOiBuYW1lMixcbiAgICAgIGdldCBhbGdlYnJhaWNUeXBlKCkge1xuICAgICAgICByZXR1cm4gbWFwcGVkUm93W25hbWUyXS50eXBlQnVpbGRlci5hbGdlYnJhaWNUeXBlO1xuICAgICAgfVxuICAgIH0pKTtcbiAgICBzdXBlcihBbGdlYnJhaWNUeXBlLlByb2R1Y3QoeyBlbGVtZW50cyB9KSk7XG4gICAgdGhpcy5yb3cgPSBtYXBwZWRSb3c7XG4gICAgdGhpcy50eXBlTmFtZSA9IG5hbWU7XG4gIH1cbn07XG52YXIgU3VtQnVpbGRlckltcGwgPSBjbGFzcyBleHRlbmRzIFR5cGVCdWlsZGVyIHtcbiAgdmFyaWFudHM7XG4gIHR5cGVOYW1lO1xuICBjb25zdHJ1Y3Rvcih2YXJpYW50cywgbmFtZSkge1xuICAgIGZ1bmN0aW9uIHZhcmlhbnRzQXJyYXlGcm9tVmFyaWFudHNPYmoodmFyaWFudHMyKSB7XG4gICAgICByZXR1cm4gT2JqZWN0LmtleXModmFyaWFudHMyKS5tYXAoKGtleSkgPT4gKHtcbiAgICAgICAgbmFtZToga2V5LFxuICAgICAgICAvLyBMYXppbHkgcmVzb2x2ZSB0aGUgdW5kZXJseWluZyBvYmplY3QncyBhbGdlYnJhaWNUeXBlLlxuICAgICAgICAvLyBUaGlzIHdpbGwgY2FsbCBvYmpba2V5XS5hbGdlYnJhaWNUeXBlIG9ubHkgd2hlbiBzb21lb25lXG4gICAgICAgIC8vIGFjdHVhbGx5IHJlYWRzIHRoaXMgcHJvcGVydHkuXG4gICAgICAgIGdldCBhbGdlYnJhaWNUeXBlKCkge1xuICAgICAgICAgIHJldHVybiB2YXJpYW50czJba2V5XS5hbGdlYnJhaWNUeXBlO1xuICAgICAgICB9XG4gICAgICB9KSk7XG4gICAgfVxuICAgIHN1cGVyKFxuICAgICAgQWxnZWJyYWljVHlwZS5TdW0oe1xuICAgICAgICB2YXJpYW50czogdmFyaWFudHNBcnJheUZyb21WYXJpYW50c09iaih2YXJpYW50cylcbiAgICAgIH0pXG4gICAgKTtcbiAgICB0aGlzLnZhcmlhbnRzID0gdmFyaWFudHM7XG4gICAgdGhpcy50eXBlTmFtZSA9IG5hbWU7XG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXModmFyaWFudHMpKSB7XG4gICAgICBjb25zdCBkZXNjID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih2YXJpYW50cywga2V5KTtcbiAgICAgIGNvbnN0IGlzQWNjZXNzb3IgPSAhIWRlc2MgJiYgKHR5cGVvZiBkZXNjLmdldCA9PT0gXCJmdW5jdGlvblwiIHx8IHR5cGVvZiBkZXNjLnNldCA9PT0gXCJmdW5jdGlvblwiKTtcbiAgICAgIGxldCBpc1VuaXQyID0gZmFsc2U7XG4gICAgICBpZiAoIWlzQWNjZXNzb3IpIHtcbiAgICAgICAgY29uc3QgdmFyaWFudCA9IHZhcmlhbnRzW2tleV07XG4gICAgICAgIGlzVW5pdDIgPSB2YXJpYW50IGluc3RhbmNlb2YgVW5pdEJ1aWxkZXI7XG4gICAgICB9XG4gICAgICBpZiAoaXNVbml0Mikge1xuICAgICAgICBjb25zdCBjb25zdGFudCA9IHRoaXMuY3JlYXRlKGtleSk7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBrZXksIHtcbiAgICAgICAgICB2YWx1ZTogY29uc3RhbnQsXG4gICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGZuID0gKCh2YWx1ZSkgPT4gdGhpcy5jcmVhdGUoa2V5LCB2YWx1ZSkpO1xuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywga2V5LCB7XG4gICAgICAgICAgdmFsdWU6IGZuLFxuICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgIGNvbmZpZ3VyYWJsZTogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGNyZWF0ZSh0YWcsIHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSB2b2lkIDAgPyB7IHRhZyB9IDogeyB0YWcsIHZhbHVlIH07XG4gIH1cbiAgZGVmYXVsdCh2YWx1ZSkge1xuICAgIHJldHVybiBuZXcgU3VtQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGRlZmF1bHRWYWx1ZTogdmFsdWUgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgU3VtQ29sdW1uQnVpbGRlcih0aGlzLCBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IG5hbWUgfSkpO1xuICB9XG59O1xudmFyIFN1bUJ1aWxkZXIgPSBTdW1CdWlsZGVySW1wbDtcbnZhciBTaW1wbGVTdW1CdWlsZGVySW1wbCA9IGNsYXNzIGV4dGVuZHMgU3VtQnVpbGRlckltcGwge1xuICBpbmRleChhbGdvcml0aG0gPSBcImJ0cmVlXCIpIHtcbiAgICByZXR1cm4gbmV3IFNpbXBsZVN1bUNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgcHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gbmV3IFNpbXBsZVN1bUNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc1ByaW1hcnlLZXk6IHRydWUgfSlcbiAgICApO1xuICB9XG59O1xudmFyIFNpbXBsZVN1bUJ1aWxkZXIgPSBTaW1wbGVTdW1CdWlsZGVySW1wbDtcbnZhciBTY2hlZHVsZUF0QnVpbGRlciA9IGNsYXNzIGV4dGVuZHMgVHlwZUJ1aWxkZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihzY2hlZHVsZV9hdF9kZWZhdWx0LmdldEFsZ2VicmFpY1R5cGUoKSk7XG4gIH1cbiAgZGVmYXVsdCh2YWx1ZSkge1xuICAgIHJldHVybiBuZXcgU2NoZWR1bGVBdENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBkZWZhdWx0VmFsdWU6IHZhbHVlIH0pXG4gICAgKTtcbiAgfVxuICBuYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFNjaGVkdWxlQXRDb2x1bW5CdWlsZGVyKHRoaXMsIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgbmFtZSB9KSk7XG4gIH1cbn07XG52YXIgSWRlbnRpdHlCdWlsZGVyID0gY2xhc3MgZXh0ZW5kcyBUeXBlQnVpbGRlciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKElkZW50aXR5LmdldEFsZ2VicmFpY1R5cGUoKSk7XG4gIH1cbiAgaW5kZXgoYWxnb3JpdGhtID0gXCJidHJlZVwiKSB7XG4gICAgcmV0dXJuIG5ldyBJZGVudGl0eUNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgdW5pcXVlKCkge1xuICAgIHJldHVybiBuZXcgSWRlbnRpdHlDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaXNVbmlxdWU6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIHByaW1hcnlLZXkoKSB7XG4gICAgcmV0dXJuIG5ldyBJZGVudGl0eUNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc1ByaW1hcnlLZXk6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGF1dG9JbmMoKSB7XG4gICAgcmV0dXJuIG5ldyBJZGVudGl0eUNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc0F1dG9JbmNyZW1lbnQ6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IElkZW50aXR5Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGRlZmF1bHRWYWx1ZTogdmFsdWUgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgSWRlbnRpdHlDb2x1bW5CdWlsZGVyKHRoaXMsIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgbmFtZSB9KSk7XG4gIH1cbn07XG52YXIgQ29ubmVjdGlvbklkQnVpbGRlciA9IGNsYXNzIGV4dGVuZHMgVHlwZUJ1aWxkZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihDb25uZWN0aW9uSWQuZ2V0QWxnZWJyYWljVHlwZSgpKTtcbiAgfVxuICBpbmRleChhbGdvcml0aG0gPSBcImJ0cmVlXCIpIHtcbiAgICByZXR1cm4gbmV3IENvbm5lY3Rpb25JZENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgdW5pcXVlKCkge1xuICAgIHJldHVybiBuZXcgQ29ubmVjdGlvbklkQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGlzVW5pcXVlOiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBwcmltYXJ5S2V5KCkge1xuICAgIHJldHVybiBuZXcgQ29ubmVjdGlvbklkQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGlzUHJpbWFyeUtleTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgYXV0b0luYygpIHtcbiAgICByZXR1cm4gbmV3IENvbm5lY3Rpb25JZENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc0F1dG9JbmNyZW1lbnQ6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IENvbm5lY3Rpb25JZENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBkZWZhdWx0VmFsdWU6IHZhbHVlIH0pXG4gICAgKTtcbiAgfVxuICBuYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IENvbm5lY3Rpb25JZENvbHVtbkJ1aWxkZXIodGhpcywgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBuYW1lIH0pKTtcbiAgfVxufTtcbnZhciBUaW1lc3RhbXBCdWlsZGVyID0gY2xhc3MgZXh0ZW5kcyBUeXBlQnVpbGRlciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKFRpbWVzdGFtcC5nZXRBbGdlYnJhaWNUeXBlKCkpO1xuICB9XG4gIGluZGV4KGFsZ29yaXRobSA9IFwiYnRyZWVcIikge1xuICAgIHJldHVybiBuZXcgVGltZXN0YW1wQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGluZGV4VHlwZTogYWxnb3JpdGhtIH0pXG4gICAgKTtcbiAgfVxuICB1bmlxdWUoKSB7XG4gICAgcmV0dXJuIG5ldyBUaW1lc3RhbXBDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaXNVbmlxdWU6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIHByaW1hcnlLZXkoKSB7XG4gICAgcmV0dXJuIG5ldyBUaW1lc3RhbXBDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaXNQcmltYXJ5S2V5OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBhdXRvSW5jKCkge1xuICAgIHJldHVybiBuZXcgVGltZXN0YW1wQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGlzQXV0b0luY3JlbWVudDogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgZGVmYXVsdCh2YWx1ZSkge1xuICAgIHJldHVybiBuZXcgVGltZXN0YW1wQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMsXG4gICAgICBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IGRlZmF1bHRWYWx1ZTogdmFsdWUgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgVGltZXN0YW1wQ29sdW1uQnVpbGRlcih0aGlzLCBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IG5hbWUgfSkpO1xuICB9XG59O1xudmFyIFRpbWVEdXJhdGlvbkJ1aWxkZXIgPSBjbGFzcyBleHRlbmRzIFR5cGVCdWlsZGVyIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoVGltZUR1cmF0aW9uLmdldEFsZ2VicmFpY1R5cGUoKSk7XG4gIH1cbiAgaW5kZXgoYWxnb3JpdGhtID0gXCJidHJlZVwiKSB7XG4gICAgcmV0dXJuIG5ldyBUaW1lRHVyYXRpb25Db2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaW5kZXhUeXBlOiBhbGdvcml0aG0gfSlcbiAgICApO1xuICB9XG4gIHVuaXF1ZSgpIHtcbiAgICByZXR1cm4gbmV3IFRpbWVEdXJhdGlvbkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc1VuaXF1ZTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgcHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gbmV3IFRpbWVEdXJhdGlvbkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc1ByaW1hcnlLZXk6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGF1dG9JbmMoKSB7XG4gICAgcmV0dXJuIG5ldyBUaW1lRHVyYXRpb25Db2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaXNBdXRvSW5jcmVtZW50OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBUaW1lRHVyYXRpb25Db2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgZGVmYXVsdFZhbHVlOiB2YWx1ZSB9KVxuICAgICk7XG4gIH1cbiAgbmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBUaW1lRHVyYXRpb25Db2x1bW5CdWlsZGVyKHRoaXMsIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgbmFtZSB9KSk7XG4gIH1cbn07XG52YXIgVXVpZEJ1aWxkZXIgPSBjbGFzcyBleHRlbmRzIFR5cGVCdWlsZGVyIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoVXVpZC5nZXRBbGdlYnJhaWNUeXBlKCkpO1xuICB9XG4gIGluZGV4KGFsZ29yaXRobSA9IFwiYnRyZWVcIikge1xuICAgIHJldHVybiBuZXcgVXVpZENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgdW5pcXVlKCkge1xuICAgIHJldHVybiBuZXcgVXVpZENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc1VuaXF1ZTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgcHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gbmV3IFV1aWRDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgaXNQcmltYXJ5S2V5OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBhdXRvSW5jKCkge1xuICAgIHJldHVybiBuZXcgVXVpZENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLFxuICAgICAgc2V0KGRlZmF1bHRNZXRhZGF0YSwgeyBpc0F1dG9JbmNyZW1lbnQ6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IFV1aWRDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcyxcbiAgICAgIHNldChkZWZhdWx0TWV0YWRhdGEsIHsgZGVmYXVsdFZhbHVlOiB2YWx1ZSB9KVxuICAgICk7XG4gIH1cbiAgbmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBVdWlkQ29sdW1uQnVpbGRlcih0aGlzLCBzZXQoZGVmYXVsdE1ldGFkYXRhLCB7IG5hbWUgfSkpO1xuICB9XG59O1xudmFyIGRlZmF1bHRNZXRhZGF0YSA9IHt9O1xudmFyIENvbHVtbkJ1aWxkZXIgPSBjbGFzcyB7XG4gIHR5cGVCdWlsZGVyO1xuICBjb2x1bW5NZXRhZGF0YTtcbiAgY29uc3RydWN0b3IodHlwZUJ1aWxkZXIsIG1ldGFkYXRhKSB7XG4gICAgdGhpcy50eXBlQnVpbGRlciA9IHR5cGVCdWlsZGVyO1xuICAgIHRoaXMuY29sdW1uTWV0YWRhdGEgPSBtZXRhZGF0YTtcbiAgfVxuICBzZXJpYWxpemUod3JpdGVyLCB2YWx1ZSkge1xuICAgIHRoaXMudHlwZUJ1aWxkZXIuc2VyaWFsaXplKHdyaXRlciwgdmFsdWUpO1xuICB9XG4gIGRlc2VyaWFsaXplKHJlYWRlcikge1xuICAgIHJldHVybiB0aGlzLnR5cGVCdWlsZGVyLmRlc2VyaWFsaXplKHJlYWRlcik7XG4gIH1cbn07XG52YXIgVThDb2x1bW5CdWlsZGVyID0gY2xhc3MgX1U4Q29sdW1uQnVpbGRlciBleHRlbmRzIENvbHVtbkJ1aWxkZXIge1xuICBpbmRleChhbGdvcml0aG0gPSBcImJ0cmVlXCIpIHtcbiAgICByZXR1cm4gbmV3IF9VOENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaW5kZXhUeXBlOiBhbGdvcml0aG0gfSlcbiAgICApO1xuICB9XG4gIHVuaXF1ZSgpIHtcbiAgICByZXR1cm4gbmV3IF9VOENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaXNVbmlxdWU6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIHByaW1hcnlLZXkoKSB7XG4gICAgcmV0dXJuIG5ldyBfVThDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGlzUHJpbWFyeUtleTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgYXV0b0luYygpIHtcbiAgICByZXR1cm4gbmV3IF9VOENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaXNBdXRvSW5jcmVtZW50OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBfVThDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7XG4gICAgICAgIGRlZmF1bHRWYWx1ZTogdmFsdWVcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuICBuYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IF9VOENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgbmFtZSB9KVxuICAgICk7XG4gIH1cbn07XG52YXIgVTE2Q29sdW1uQnVpbGRlciA9IGNsYXNzIF9VMTZDb2x1bW5CdWlsZGVyIGV4dGVuZHMgQ29sdW1uQnVpbGRlciB7XG4gIGluZGV4KGFsZ29yaXRobSA9IFwiYnRyZWVcIikge1xuICAgIHJldHVybiBuZXcgX1UxNkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaW5kZXhUeXBlOiBhbGdvcml0aG0gfSlcbiAgICApO1xuICB9XG4gIHVuaXF1ZSgpIHtcbiAgICByZXR1cm4gbmV3IF9VMTZDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGlzVW5pcXVlOiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBwcmltYXJ5S2V5KCkge1xuICAgIHJldHVybiBuZXcgX1UxNkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaXNQcmltYXJ5S2V5OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBhdXRvSW5jKCkge1xuICAgIHJldHVybiBuZXcgX1UxNkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaXNBdXRvSW5jcmVtZW50OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBfVTE2Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwge1xuICAgICAgICBkZWZhdWx0VmFsdWU6IHZhbHVlXG4gICAgICB9KVxuICAgICk7XG4gIH1cbiAgbmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBfVTE2Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBuYW1lIH0pXG4gICAgKTtcbiAgfVxufTtcbnZhciBVMzJDb2x1bW5CdWlsZGVyID0gY2xhc3MgX1UzMkNvbHVtbkJ1aWxkZXIgZXh0ZW5kcyBDb2x1bW5CdWlsZGVyIHtcbiAgaW5kZXgoYWxnb3JpdGhtID0gXCJidHJlZVwiKSB7XG4gICAgcmV0dXJuIG5ldyBfVTMyQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgdW5pcXVlKCkge1xuICAgIHJldHVybiBuZXcgX1UzMkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaXNVbmlxdWU6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIHByaW1hcnlLZXkoKSB7XG4gICAgcmV0dXJuIG5ldyBfVTMyQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc1ByaW1hcnlLZXk6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGF1dG9JbmMoKSB7XG4gICAgcmV0dXJuIG5ldyBfVTMyQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc0F1dG9JbmNyZW1lbnQ6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IF9VMzJDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7XG4gICAgICAgIGRlZmF1bHRWYWx1ZTogdmFsdWVcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuICBuYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IF9VMzJDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IG5hbWUgfSlcbiAgICApO1xuICB9XG59O1xudmFyIFU2NENvbHVtbkJ1aWxkZXIgPSBjbGFzcyBfVTY0Q29sdW1uQnVpbGRlciBleHRlbmRzIENvbHVtbkJ1aWxkZXIge1xuICBpbmRleChhbGdvcml0aG0gPSBcImJ0cmVlXCIpIHtcbiAgICByZXR1cm4gbmV3IF9VNjRDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGluZGV4VHlwZTogYWxnb3JpdGhtIH0pXG4gICAgKTtcbiAgfVxuICB1bmlxdWUoKSB7XG4gICAgcmV0dXJuIG5ldyBfVTY0Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc1VuaXF1ZTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgcHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gbmV3IF9VNjRDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGlzUHJpbWFyeUtleTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgYXV0b0luYygpIHtcbiAgICByZXR1cm4gbmV3IF9VNjRDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGlzQXV0b0luY3JlbWVudDogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgZGVmYXVsdCh2YWx1ZSkge1xuICAgIHJldHVybiBuZXcgX1U2NENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHtcbiAgICAgICAgZGVmYXVsdFZhbHVlOiB2YWx1ZVxuICAgICAgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgX1U2NENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgbmFtZSB9KVxuICAgICk7XG4gIH1cbn07XG52YXIgVTEyOENvbHVtbkJ1aWxkZXIgPSBjbGFzcyBfVTEyOENvbHVtbkJ1aWxkZXIgZXh0ZW5kcyBDb2x1bW5CdWlsZGVyIHtcbiAgaW5kZXgoYWxnb3JpdGhtID0gXCJidHJlZVwiKSB7XG4gICAgcmV0dXJuIG5ldyBfVTEyOENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaW5kZXhUeXBlOiBhbGdvcml0aG0gfSlcbiAgICApO1xuICB9XG4gIHVuaXF1ZSgpIHtcbiAgICByZXR1cm4gbmV3IF9VMTI4Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc1VuaXF1ZTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgcHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gbmV3IF9VMTI4Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc1ByaW1hcnlLZXk6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGF1dG9JbmMoKSB7XG4gICAgcmV0dXJuIG5ldyBfVTEyOENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaXNBdXRvSW5jcmVtZW50OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBfVTEyOENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHtcbiAgICAgICAgZGVmYXVsdFZhbHVlOiB2YWx1ZVxuICAgICAgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgX1UxMjhDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IG5hbWUgfSlcbiAgICApO1xuICB9XG59O1xudmFyIFUyNTZDb2x1bW5CdWlsZGVyID0gY2xhc3MgX1UyNTZDb2x1bW5CdWlsZGVyIGV4dGVuZHMgQ29sdW1uQnVpbGRlciB7XG4gIGluZGV4KGFsZ29yaXRobSA9IFwiYnRyZWVcIikge1xuICAgIHJldHVybiBuZXcgX1UyNTZDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGluZGV4VHlwZTogYWxnb3JpdGhtIH0pXG4gICAgKTtcbiAgfVxuICB1bmlxdWUoKSB7XG4gICAgcmV0dXJuIG5ldyBfVTI1NkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaXNVbmlxdWU6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIHByaW1hcnlLZXkoKSB7XG4gICAgcmV0dXJuIG5ldyBfVTI1NkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaXNQcmltYXJ5S2V5OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBhdXRvSW5jKCkge1xuICAgIHJldHVybiBuZXcgX1UyNTZDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGlzQXV0b0luY3JlbWVudDogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgZGVmYXVsdCh2YWx1ZSkge1xuICAgIHJldHVybiBuZXcgX1UyNTZDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7XG4gICAgICAgIGRlZmF1bHRWYWx1ZTogdmFsdWVcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuICBuYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IF9VMjU2Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBuYW1lIH0pXG4gICAgKTtcbiAgfVxufTtcbnZhciBJOENvbHVtbkJ1aWxkZXIgPSBjbGFzcyBfSThDb2x1bW5CdWlsZGVyIGV4dGVuZHMgQ29sdW1uQnVpbGRlciB7XG4gIGluZGV4KGFsZ29yaXRobSA9IFwiYnRyZWVcIikge1xuICAgIHJldHVybiBuZXcgX0k4Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgdW5pcXVlKCkge1xuICAgIHJldHVybiBuZXcgX0k4Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc1VuaXF1ZTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgcHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gbmV3IF9JOENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaXNQcmltYXJ5S2V5OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBhdXRvSW5jKCkge1xuICAgIHJldHVybiBuZXcgX0k4Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc0F1dG9JbmNyZW1lbnQ6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IF9JOENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHtcbiAgICAgICAgZGVmYXVsdFZhbHVlOiB2YWx1ZVxuICAgICAgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgX0k4Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBuYW1lIH0pXG4gICAgKTtcbiAgfVxufTtcbnZhciBJMTZDb2x1bW5CdWlsZGVyID0gY2xhc3MgX0kxNkNvbHVtbkJ1aWxkZXIgZXh0ZW5kcyBDb2x1bW5CdWlsZGVyIHtcbiAgaW5kZXgoYWxnb3JpdGhtID0gXCJidHJlZVwiKSB7XG4gICAgcmV0dXJuIG5ldyBfSTE2Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgdW5pcXVlKCkge1xuICAgIHJldHVybiBuZXcgX0kxNkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaXNVbmlxdWU6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIHByaW1hcnlLZXkoKSB7XG4gICAgcmV0dXJuIG5ldyBfSTE2Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc1ByaW1hcnlLZXk6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGF1dG9JbmMoKSB7XG4gICAgcmV0dXJuIG5ldyBfSTE2Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc0F1dG9JbmNyZW1lbnQ6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IF9JMTZDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7XG4gICAgICAgIGRlZmF1bHRWYWx1ZTogdmFsdWVcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuICBuYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IF9JMTZDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IG5hbWUgfSlcbiAgICApO1xuICB9XG59O1xudmFyIEkzMkNvbHVtbkJ1aWxkZXIgPSBjbGFzcyBfSTMyQ29sdW1uQnVpbGRlciBleHRlbmRzIENvbHVtbkJ1aWxkZXIge1xuICBpbmRleChhbGdvcml0aG0gPSBcImJ0cmVlXCIpIHtcbiAgICByZXR1cm4gbmV3IF9JMzJDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGluZGV4VHlwZTogYWxnb3JpdGhtIH0pXG4gICAgKTtcbiAgfVxuICB1bmlxdWUoKSB7XG4gICAgcmV0dXJuIG5ldyBfSTMyQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc1VuaXF1ZTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgcHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gbmV3IF9JMzJDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGlzUHJpbWFyeUtleTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgYXV0b0luYygpIHtcbiAgICByZXR1cm4gbmV3IF9JMzJDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGlzQXV0b0luY3JlbWVudDogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgZGVmYXVsdCh2YWx1ZSkge1xuICAgIHJldHVybiBuZXcgX0kzMkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHtcbiAgICAgICAgZGVmYXVsdFZhbHVlOiB2YWx1ZVxuICAgICAgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgX0kzMkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgbmFtZSB9KVxuICAgICk7XG4gIH1cbn07XG52YXIgSTY0Q29sdW1uQnVpbGRlciA9IGNsYXNzIF9JNjRDb2x1bW5CdWlsZGVyIGV4dGVuZHMgQ29sdW1uQnVpbGRlciB7XG4gIGluZGV4KGFsZ29yaXRobSA9IFwiYnRyZWVcIikge1xuICAgIHJldHVybiBuZXcgX0k2NENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaW5kZXhUeXBlOiBhbGdvcml0aG0gfSlcbiAgICApO1xuICB9XG4gIHVuaXF1ZSgpIHtcbiAgICByZXR1cm4gbmV3IF9JNjRDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGlzVW5pcXVlOiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBwcmltYXJ5S2V5KCkge1xuICAgIHJldHVybiBuZXcgX0k2NENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaXNQcmltYXJ5S2V5OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBhdXRvSW5jKCkge1xuICAgIHJldHVybiBuZXcgX0k2NENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaXNBdXRvSW5jcmVtZW50OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBfSTY0Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwge1xuICAgICAgICBkZWZhdWx0VmFsdWU6IHZhbHVlXG4gICAgICB9KVxuICAgICk7XG4gIH1cbiAgbmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBfSTY0Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBuYW1lIH0pXG4gICAgKTtcbiAgfVxufTtcbnZhciBJMTI4Q29sdW1uQnVpbGRlciA9IGNsYXNzIF9JMTI4Q29sdW1uQnVpbGRlciBleHRlbmRzIENvbHVtbkJ1aWxkZXIge1xuICBpbmRleChhbGdvcml0aG0gPSBcImJ0cmVlXCIpIHtcbiAgICByZXR1cm4gbmV3IF9JMTI4Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgdW5pcXVlKCkge1xuICAgIHJldHVybiBuZXcgX0kxMjhDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGlzVW5pcXVlOiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBwcmltYXJ5S2V5KCkge1xuICAgIHJldHVybiBuZXcgX0kxMjhDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGlzUHJpbWFyeUtleTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgYXV0b0luYygpIHtcbiAgICByZXR1cm4gbmV3IF9JMTI4Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc0F1dG9JbmNyZW1lbnQ6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IF9JMTI4Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwge1xuICAgICAgICBkZWZhdWx0VmFsdWU6IHZhbHVlXG4gICAgICB9KVxuICAgICk7XG4gIH1cbiAgbmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBfSTEyOENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgbmFtZSB9KVxuICAgICk7XG4gIH1cbn07XG52YXIgSTI1NkNvbHVtbkJ1aWxkZXIgPSBjbGFzcyBfSTI1NkNvbHVtbkJ1aWxkZXIgZXh0ZW5kcyBDb2x1bW5CdWlsZGVyIHtcbiAgaW5kZXgoYWxnb3JpdGhtID0gXCJidHJlZVwiKSB7XG4gICAgcmV0dXJuIG5ldyBfSTI1NkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaW5kZXhUeXBlOiBhbGdvcml0aG0gfSlcbiAgICApO1xuICB9XG4gIHVuaXF1ZSgpIHtcbiAgICByZXR1cm4gbmV3IF9JMjU2Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc1VuaXF1ZTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgcHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gbmV3IF9JMjU2Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc1ByaW1hcnlLZXk6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGF1dG9JbmMoKSB7XG4gICAgcmV0dXJuIG5ldyBfSTI1NkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaXNBdXRvSW5jcmVtZW50OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBfSTI1NkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHtcbiAgICAgICAgZGVmYXVsdFZhbHVlOiB2YWx1ZVxuICAgICAgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgX0kyNTZDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IG5hbWUgfSlcbiAgICApO1xuICB9XG59O1xudmFyIEYzMkNvbHVtbkJ1aWxkZXIgPSBjbGFzcyBfRjMyQ29sdW1uQnVpbGRlciBleHRlbmRzIENvbHVtbkJ1aWxkZXIge1xuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBfRjMyQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwge1xuICAgICAgICBkZWZhdWx0VmFsdWU6IHZhbHVlXG4gICAgICB9KVxuICAgICk7XG4gIH1cbiAgbmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBfRjMyQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBuYW1lIH0pXG4gICAgKTtcbiAgfVxufTtcbnZhciBGNjRDb2x1bW5CdWlsZGVyID0gY2xhc3MgX0Y2NENvbHVtbkJ1aWxkZXIgZXh0ZW5kcyBDb2x1bW5CdWlsZGVyIHtcbiAgZGVmYXVsdCh2YWx1ZSkge1xuICAgIHJldHVybiBuZXcgX0Y2NENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHtcbiAgICAgICAgZGVmYXVsdFZhbHVlOiB2YWx1ZVxuICAgICAgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgX0Y2NENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgbmFtZSB9KVxuICAgICk7XG4gIH1cbn07XG52YXIgQm9vbENvbHVtbkJ1aWxkZXIgPSBjbGFzcyBfQm9vbENvbHVtbkJ1aWxkZXIgZXh0ZW5kcyBDb2x1bW5CdWlsZGVyIHtcbiAgaW5kZXgoYWxnb3JpdGhtID0gXCJidHJlZVwiKSB7XG4gICAgcmV0dXJuIG5ldyBfQm9vbENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaW5kZXhUeXBlOiBhbGdvcml0aG0gfSlcbiAgICApO1xuICB9XG4gIHVuaXF1ZSgpIHtcbiAgICByZXR1cm4gbmV3IF9Cb29sQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc1VuaXF1ZTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgcHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gbmV3IF9Cb29sQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc1ByaW1hcnlLZXk6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IF9Cb29sQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwge1xuICAgICAgICBkZWZhdWx0VmFsdWU6IHZhbHVlXG4gICAgICB9KVxuICAgICk7XG4gIH1cbiAgbmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBfQm9vbENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgbmFtZSB9KVxuICAgICk7XG4gIH1cbn07XG52YXIgU3RyaW5nQ29sdW1uQnVpbGRlciA9IGNsYXNzIF9TdHJpbmdDb2x1bW5CdWlsZGVyIGV4dGVuZHMgQ29sdW1uQnVpbGRlciB7XG4gIGluZGV4KGFsZ29yaXRobSA9IFwiYnRyZWVcIikge1xuICAgIHJldHVybiBuZXcgX1N0cmluZ0NvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaW5kZXhUeXBlOiBhbGdvcml0aG0gfSlcbiAgICApO1xuICB9XG4gIHVuaXF1ZSgpIHtcbiAgICByZXR1cm4gbmV3IF9TdHJpbmdDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGlzVW5pcXVlOiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBwcmltYXJ5S2V5KCkge1xuICAgIHJldHVybiBuZXcgX1N0cmluZ0NvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaXNQcmltYXJ5S2V5OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBfU3RyaW5nQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwge1xuICAgICAgICBkZWZhdWx0VmFsdWU6IHZhbHVlXG4gICAgICB9KVxuICAgICk7XG4gIH1cbiAgbmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBfU3RyaW5nQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBuYW1lIH0pXG4gICAgKTtcbiAgfVxufTtcbnZhciBBcnJheUNvbHVtbkJ1aWxkZXIgPSBjbGFzcyBfQXJyYXlDb2x1bW5CdWlsZGVyIGV4dGVuZHMgQ29sdW1uQnVpbGRlciB7XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IF9BcnJheUNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHtcbiAgICAgICAgZGVmYXVsdFZhbHVlOiB2YWx1ZVxuICAgICAgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgX0FycmF5Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBuYW1lIH0pXG4gICAgKTtcbiAgfVxufTtcbnZhciBCeXRlQXJyYXlDb2x1bW5CdWlsZGVyID0gY2xhc3MgX0J5dGVBcnJheUNvbHVtbkJ1aWxkZXIgZXh0ZW5kcyBDb2x1bW5CdWlsZGVyIHtcbiAgY29uc3RydWN0b3IobWV0YWRhdGEpIHtcbiAgICBzdXBlcihuZXcgVHlwZUJ1aWxkZXIoQWxnZWJyYWljVHlwZS5BcnJheShBbGdlYnJhaWNUeXBlLlU4KSksIG1ldGFkYXRhKTtcbiAgfVxuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBfQnl0ZUFycmF5Q29sdW1uQnVpbGRlcihcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGRlZmF1bHRWYWx1ZTogdmFsdWUgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgX0J5dGVBcnJheUNvbHVtbkJ1aWxkZXIoc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgbmFtZSB9KSk7XG4gIH1cbn07XG52YXIgT3B0aW9uQ29sdW1uQnVpbGRlciA9IGNsYXNzIF9PcHRpb25Db2x1bW5CdWlsZGVyIGV4dGVuZHMgQ29sdW1uQnVpbGRlciB7XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IF9PcHRpb25Db2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7XG4gICAgICAgIGRlZmF1bHRWYWx1ZTogdmFsdWVcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxuICBuYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IF9PcHRpb25Db2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IG5hbWUgfSlcbiAgICApO1xuICB9XG59O1xudmFyIFJlc3VsdENvbHVtbkJ1aWxkZXIgPSBjbGFzcyBfUmVzdWx0Q29sdW1uQnVpbGRlciBleHRlbmRzIENvbHVtbkJ1aWxkZXIge1xuICBjb25zdHJ1Y3Rvcih0eXBlQnVpbGRlciwgbWV0YWRhdGEpIHtcbiAgICBzdXBlcih0eXBlQnVpbGRlciwgbWV0YWRhdGEpO1xuICB9XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IF9SZXN1bHRDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7XG4gICAgICAgIGRlZmF1bHRWYWx1ZTogdmFsdWVcbiAgICAgIH0pXG4gICAgKTtcbiAgfVxufTtcbnZhciBQcm9kdWN0Q29sdW1uQnVpbGRlciA9IGNsYXNzIF9Qcm9kdWN0Q29sdW1uQnVpbGRlciBleHRlbmRzIENvbHVtbkJ1aWxkZXIge1xuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBfUHJvZHVjdENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgZGVmYXVsdFZhbHVlOiB2YWx1ZSB9KVxuICAgICk7XG4gIH1cbiAgbmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBfUHJvZHVjdENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgbmFtZSB9KVxuICAgICk7XG4gIH1cbn07XG52YXIgU3VtQ29sdW1uQnVpbGRlciA9IGNsYXNzIF9TdW1Db2x1bW5CdWlsZGVyIGV4dGVuZHMgQ29sdW1uQnVpbGRlciB7XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IF9TdW1Db2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGRlZmF1bHRWYWx1ZTogdmFsdWUgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgX1N1bUNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgbmFtZSB9KVxuICAgICk7XG4gIH1cbn07XG52YXIgU2ltcGxlU3VtQ29sdW1uQnVpbGRlciA9IGNsYXNzIF9TaW1wbGVTdW1Db2x1bW5CdWlsZGVyIGV4dGVuZHMgU3VtQ29sdW1uQnVpbGRlciB7XG4gIGluZGV4KGFsZ29yaXRobSA9IFwiYnRyZWVcIikge1xuICAgIHJldHVybiBuZXcgX1NpbXBsZVN1bUNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaW5kZXhUeXBlOiBhbGdvcml0aG0gfSlcbiAgICApO1xuICB9XG4gIHByaW1hcnlLZXkoKSB7XG4gICAgcmV0dXJuIG5ldyBfU2ltcGxlU3VtQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc1ByaW1hcnlLZXk6IHRydWUgfSlcbiAgICApO1xuICB9XG59O1xudmFyIFNjaGVkdWxlQXRDb2x1bW5CdWlsZGVyID0gY2xhc3MgX1NjaGVkdWxlQXRDb2x1bW5CdWlsZGVyIGV4dGVuZHMgQ29sdW1uQnVpbGRlciB7XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IF9TY2hlZHVsZUF0Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBkZWZhdWx0VmFsdWU6IHZhbHVlIH0pXG4gICAgKTtcbiAgfVxuICBuYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IF9TY2hlZHVsZUF0Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBuYW1lIH0pXG4gICAgKTtcbiAgfVxufTtcbnZhciBJZGVudGl0eUNvbHVtbkJ1aWxkZXIgPSBjbGFzcyBfSWRlbnRpdHlDb2x1bW5CdWlsZGVyIGV4dGVuZHMgQ29sdW1uQnVpbGRlciB7XG4gIGluZGV4KGFsZ29yaXRobSA9IFwiYnRyZWVcIikge1xuICAgIHJldHVybiBuZXcgX0lkZW50aXR5Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgdW5pcXVlKCkge1xuICAgIHJldHVybiBuZXcgX0lkZW50aXR5Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc1VuaXF1ZTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgcHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gbmV3IF9JZGVudGl0eUNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaXNQcmltYXJ5S2V5OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBfSWRlbnRpdHlDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGRlZmF1bHRWYWx1ZTogdmFsdWUgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgX0lkZW50aXR5Q29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBuYW1lIH0pXG4gICAgKTtcbiAgfVxufTtcbnZhciBDb25uZWN0aW9uSWRDb2x1bW5CdWlsZGVyID0gY2xhc3MgX0Nvbm5lY3Rpb25JZENvbHVtbkJ1aWxkZXIgZXh0ZW5kcyBDb2x1bW5CdWlsZGVyIHtcbiAgaW5kZXgoYWxnb3JpdGhtID0gXCJidHJlZVwiKSB7XG4gICAgcmV0dXJuIG5ldyBfQ29ubmVjdGlvbklkQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgdW5pcXVlKCkge1xuICAgIHJldHVybiBuZXcgX0Nvbm5lY3Rpb25JZENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaXNVbmlxdWU6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIHByaW1hcnlLZXkoKSB7XG4gICAgcmV0dXJuIG5ldyBfQ29ubmVjdGlvbklkQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc1ByaW1hcnlLZXk6IHRydWUgfSlcbiAgICApO1xuICB9XG4gIGRlZmF1bHQodmFsdWUpIHtcbiAgICByZXR1cm4gbmV3IF9Db25uZWN0aW9uSWRDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGRlZmF1bHRWYWx1ZTogdmFsdWUgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgX0Nvbm5lY3Rpb25JZENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgbmFtZSB9KVxuICAgICk7XG4gIH1cbn07XG52YXIgVGltZXN0YW1wQ29sdW1uQnVpbGRlciA9IGNsYXNzIF9UaW1lc3RhbXBDb2x1bW5CdWlsZGVyIGV4dGVuZHMgQ29sdW1uQnVpbGRlciB7XG4gIGluZGV4KGFsZ29yaXRobSA9IFwiYnRyZWVcIikge1xuICAgIHJldHVybiBuZXcgX1RpbWVzdGFtcENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaW5kZXhUeXBlOiBhbGdvcml0aG0gfSlcbiAgICApO1xuICB9XG4gIHVuaXF1ZSgpIHtcbiAgICByZXR1cm4gbmV3IF9UaW1lc3RhbXBDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGlzVW5pcXVlOiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBwcmltYXJ5S2V5KCkge1xuICAgIHJldHVybiBuZXcgX1RpbWVzdGFtcENvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgaXNQcmltYXJ5S2V5OiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBkZWZhdWx0KHZhbHVlKSB7XG4gICAgcmV0dXJuIG5ldyBfVGltZXN0YW1wQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBkZWZhdWx0VmFsdWU6IHZhbHVlIH0pXG4gICAgKTtcbiAgfVxuICBuYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IF9UaW1lc3RhbXBDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IG5hbWUgfSlcbiAgICApO1xuICB9XG59O1xudmFyIFRpbWVEdXJhdGlvbkNvbHVtbkJ1aWxkZXIgPSBjbGFzcyBfVGltZUR1cmF0aW9uQ29sdW1uQnVpbGRlciBleHRlbmRzIENvbHVtbkJ1aWxkZXIge1xuICBpbmRleChhbGdvcml0aG0gPSBcImJ0cmVlXCIpIHtcbiAgICByZXR1cm4gbmV3IF9UaW1lRHVyYXRpb25Db2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGluZGV4VHlwZTogYWxnb3JpdGhtIH0pXG4gICAgKTtcbiAgfVxuICB1bmlxdWUoKSB7XG4gICAgcmV0dXJuIG5ldyBfVGltZUR1cmF0aW9uQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpc1VuaXF1ZTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgcHJpbWFyeUtleSgpIHtcbiAgICByZXR1cm4gbmV3IF9UaW1lRHVyYXRpb25Db2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGlzUHJpbWFyeUtleTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgZGVmYXVsdCh2YWx1ZSkge1xuICAgIHJldHVybiBuZXcgX1RpbWVEdXJhdGlvbkNvbHVtbkJ1aWxkZXIoXG4gICAgICB0aGlzLnR5cGVCdWlsZGVyLFxuICAgICAgc2V0KHRoaXMuY29sdW1uTWV0YWRhdGEsIHsgZGVmYXVsdFZhbHVlOiB2YWx1ZSB9KVxuICAgICk7XG4gIH1cbiAgbmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBfVGltZUR1cmF0aW9uQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBuYW1lIH0pXG4gICAgKTtcbiAgfVxufTtcbnZhciBVdWlkQ29sdW1uQnVpbGRlciA9IGNsYXNzIF9VdWlkQ29sdW1uQnVpbGRlciBleHRlbmRzIENvbHVtbkJ1aWxkZXIge1xuICBpbmRleChhbGdvcml0aG0gPSBcImJ0cmVlXCIpIHtcbiAgICByZXR1cm4gbmV3IF9VdWlkQ29sdW1uQnVpbGRlcihcbiAgICAgIHRoaXMudHlwZUJ1aWxkZXIsXG4gICAgICBzZXQodGhpcy5jb2x1bW5NZXRhZGF0YSwgeyBpbmRleFR5cGU6IGFsZ29yaXRobSB9KVxuICAgICk7XG4gIH1cbiAgdW5pcXVlKCkge1xuICAgIHJldHVybiBuZXcgX1V1aWRDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGlzVW5pcXVlOiB0cnVlIH0pXG4gICAgKTtcbiAgfVxuICBwcmltYXJ5S2V5KCkge1xuICAgIHJldHVybiBuZXcgX1V1aWRDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGlzUHJpbWFyeUtleTogdHJ1ZSB9KVxuICAgICk7XG4gIH1cbiAgZGVmYXVsdCh2YWx1ZSkge1xuICAgIHJldHVybiBuZXcgX1V1aWRDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IGRlZmF1bHRWYWx1ZTogdmFsdWUgfSlcbiAgICApO1xuICB9XG4gIG5hbWUobmFtZSkge1xuICAgIHJldHVybiBuZXcgX1V1aWRDb2x1bW5CdWlsZGVyKFxuICAgICAgdGhpcy50eXBlQnVpbGRlcixcbiAgICAgIHNldCh0aGlzLmNvbHVtbk1ldGFkYXRhLCB7IG5hbWUgfSlcbiAgICApO1xuICB9XG59O1xudmFyIFJlZkJ1aWxkZXIgPSBjbGFzcyBleHRlbmRzIFR5cGVCdWlsZGVyIHtcbiAgcmVmO1xuICAvKiogVGhlIHBoYW50b20gdHlwZSBvZiB0aGUgcG9pbnRlZSBvZiB0aGlzIHJlZi4gKi9cbiAgX19zcGFjZXRpbWVUeXBlO1xuICBjb25zdHJ1Y3RvcihyZWYpIHtcbiAgICBzdXBlcihBbGdlYnJhaWNUeXBlLlJlZihyZWYpKTtcbiAgICB0aGlzLnJlZiA9IHJlZjtcbiAgfVxufTtcbnZhciBlbnVtSW1wbCA9ICgobmFtZU9yT2JqLCBtYXliZU9iaikgPT4ge1xuICBsZXQgb2JqID0gbmFtZU9yT2JqO1xuICBsZXQgbmFtZSA9IHZvaWQgMDtcbiAgaWYgKHR5cGVvZiBuYW1lT3JPYmogPT09IFwic3RyaW5nXCIpIHtcbiAgICBpZiAoIW1heWJlT2JqKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuICAgICAgICBcIldoZW4gcHJvdmlkaW5nIGEgbmFtZSwgeW91IG11c3QgYWxzbyBwcm92aWRlIHRoZSB2YXJpYW50cyBvYmplY3Qgb3IgYXJyYXkuXCJcbiAgICAgICk7XG4gICAgfVxuICAgIG9iaiA9IG1heWJlT2JqO1xuICAgIG5hbWUgPSBuYW1lT3JPYmo7XG4gIH1cbiAgaWYgKEFycmF5LmlzQXJyYXkob2JqKSkge1xuICAgIGNvbnN0IHNpbXBsZVZhcmlhbnRzT2JqID0ge307XG4gICAgZm9yIChjb25zdCB2YXJpYW50IG9mIG9iaikge1xuICAgICAgc2ltcGxlVmFyaWFudHNPYmpbdmFyaWFudF0gPSBuZXcgVW5pdEJ1aWxkZXIoKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBTaW1wbGVTdW1CdWlsZGVySW1wbChzaW1wbGVWYXJpYW50c09iaiwgbmFtZSk7XG4gIH1cbiAgcmV0dXJuIG5ldyBTdW1CdWlsZGVyKG9iaiwgbmFtZSk7XG59KTtcbnZhciB0ID0ge1xuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBgQm9vbGAge0BsaW5rIEFsZ2VicmFpY1R5cGV9IHRvIGJlIHVzZWQgaW4gdGFibGUgZGVmaW5pdGlvbnNcbiAgICogUmVwcmVzZW50ZWQgYXMgYGJvb2xlYW5gIGluIFR5cGVTY3JpcHQuXG4gICAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBCb29sQnVpbGRlcn0gaW5zdGFuY2VcbiAgICovXG4gIGJvb2w6ICgpID0+IG5ldyBCb29sQnVpbGRlcigpLFxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBgU3RyaW5nYCB7QGxpbmsgQWxnZWJyYWljVHlwZX0gdG8gYmUgdXNlZCBpbiB0YWJsZSBkZWZpbml0aW9uc1xuICAgKiBSZXByZXNlbnRlZCBhcyBgc3RyaW5nYCBpbiBUeXBlU2NyaXB0LlxuICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgU3RyaW5nQnVpbGRlcn0gaW5zdGFuY2VcbiAgICovXG4gIHN0cmluZzogKCkgPT4gbmV3IFN0cmluZ0J1aWxkZXIoKSxcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgYEY2NGAge0BsaW5rIEFsZ2VicmFpY1R5cGV9IHRvIGJlIHVzZWQgaW4gdGFibGUgZGVmaW5pdGlvbnNcbiAgICogUmVwcmVzZW50ZWQgYXMgYG51bWJlcmAgaW4gVHlwZVNjcmlwdC5cbiAgICogQHJldHVybnMgQSBuZXcge0BsaW5rIEY2NEJ1aWxkZXJ9IGluc3RhbmNlXG4gICAqL1xuICBudW1iZXI6ICgpID0+IG5ldyBGNjRCdWlsZGVyKCksXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IGBJOGAge0BsaW5rIEFsZ2VicmFpY1R5cGV9IHRvIGJlIHVzZWQgaW4gdGFibGUgZGVmaW5pdGlvbnNcbiAgICogUmVwcmVzZW50ZWQgYXMgYG51bWJlcmAgaW4gVHlwZVNjcmlwdC5cbiAgICogQHJldHVybnMgQSBuZXcge0BsaW5rIEk4QnVpbGRlcn0gaW5zdGFuY2VcbiAgICovXG4gIGk4OiAoKSA9PiBuZXcgSThCdWlsZGVyKCksXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IGBVOGAge0BsaW5rIEFsZ2VicmFpY1R5cGV9IHRvIGJlIHVzZWQgaW4gdGFibGUgZGVmaW5pdGlvbnNcbiAgICogUmVwcmVzZW50ZWQgYXMgYG51bWJlcmAgaW4gVHlwZVNjcmlwdC5cbiAgICogQHJldHVybnMgQSBuZXcge0BsaW5rIFU4QnVpbGRlcn0gaW5zdGFuY2VcbiAgICovXG4gIHU4OiAoKSA9PiBuZXcgVThCdWlsZGVyKCksXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IGBJMTZgIHtAbGluayBBbGdlYnJhaWNUeXBlfSB0byBiZSB1c2VkIGluIHRhYmxlIGRlZmluaXRpb25zXG4gICAqIFJlcHJlc2VudGVkIGFzIGBudW1iZXJgIGluIFR5cGVTY3JpcHQuXG4gICAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBJMTZCdWlsZGVyfSBpbnN0YW5jZVxuICAgKi9cbiAgaTE2OiAoKSA9PiBuZXcgSTE2QnVpbGRlcigpLFxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBgVTE2YCB7QGxpbmsgQWxnZWJyYWljVHlwZX0gdG8gYmUgdXNlZCBpbiB0YWJsZSBkZWZpbml0aW9uc1xuICAgKiBSZXByZXNlbnRlZCBhcyBgbnVtYmVyYCBpbiBUeXBlU2NyaXB0LlxuICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgVTE2QnVpbGRlcn0gaW5zdGFuY2VcbiAgICovXG4gIHUxNjogKCkgPT4gbmV3IFUxNkJ1aWxkZXIoKSxcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgYEkzMmAge0BsaW5rIEFsZ2VicmFpY1R5cGV9IHRvIGJlIHVzZWQgaW4gdGFibGUgZGVmaW5pdGlvbnNcbiAgICogUmVwcmVzZW50ZWQgYXMgYG51bWJlcmAgaW4gVHlwZVNjcmlwdC5cbiAgICogQHJldHVybnMgQSBuZXcge0BsaW5rIEkzMkJ1aWxkZXJ9IGluc3RhbmNlXG4gICAqL1xuICBpMzI6ICgpID0+IG5ldyBJMzJCdWlsZGVyKCksXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IGBVMzJgIHtAbGluayBBbGdlYnJhaWNUeXBlfSB0byBiZSB1c2VkIGluIHRhYmxlIGRlZmluaXRpb25zXG4gICAqIFJlcHJlc2VudGVkIGFzIGBudW1iZXJgIGluIFR5cGVTY3JpcHQuXG4gICAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBVMzJCdWlsZGVyfSBpbnN0YW5jZVxuICAgKi9cbiAgdTMyOiAoKSA9PiBuZXcgVTMyQnVpbGRlcigpLFxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBgSTY0YCB7QGxpbmsgQWxnZWJyYWljVHlwZX0gdG8gYmUgdXNlZCBpbiB0YWJsZSBkZWZpbml0aW9uc1xuICAgKiBSZXByZXNlbnRlZCBhcyBgYmlnaW50YCBpbiBUeXBlU2NyaXB0LlxuICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgSTY0QnVpbGRlcn0gaW5zdGFuY2VcbiAgICovXG4gIGk2NDogKCkgPT4gbmV3IEk2NEJ1aWxkZXIoKSxcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgYFU2NGAge0BsaW5rIEFsZ2VicmFpY1R5cGV9IHRvIGJlIHVzZWQgaW4gdGFibGUgZGVmaW5pdGlvbnNcbiAgICogUmVwcmVzZW50ZWQgYXMgYGJpZ2ludGAgaW4gVHlwZVNjcmlwdC5cbiAgICogQHJldHVybnMgQSBuZXcge0BsaW5rIFU2NEJ1aWxkZXJ9IGluc3RhbmNlXG4gICAqL1xuICB1NjQ6ICgpID0+IG5ldyBVNjRCdWlsZGVyKCksXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IGBJMTI4YCB7QGxpbmsgQWxnZWJyYWljVHlwZX0gdG8gYmUgdXNlZCBpbiB0YWJsZSBkZWZpbml0aW9uc1xuICAgKiBSZXByZXNlbnRlZCBhcyBgYmlnaW50YCBpbiBUeXBlU2NyaXB0LlxuICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgSTEyOEJ1aWxkZXJ9IGluc3RhbmNlXG4gICAqL1xuICBpMTI4OiAoKSA9PiBuZXcgSTEyOEJ1aWxkZXIoKSxcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgYFUxMjhgIHtAbGluayBBbGdlYnJhaWNUeXBlfSB0byBiZSB1c2VkIGluIHRhYmxlIGRlZmluaXRpb25zXG4gICAqIFJlcHJlc2VudGVkIGFzIGBiaWdpbnRgIGluIFR5cGVTY3JpcHQuXG4gICAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBVMTI4QnVpbGRlcn0gaW5zdGFuY2VcbiAgICovXG4gIHUxMjg6ICgpID0+IG5ldyBVMTI4QnVpbGRlcigpLFxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBgSTI1NmAge0BsaW5rIEFsZ2VicmFpY1R5cGV9IHRvIGJlIHVzZWQgaW4gdGFibGUgZGVmaW5pdGlvbnNcbiAgICogUmVwcmVzZW50ZWQgYXMgYGJpZ2ludGAgaW4gVHlwZVNjcmlwdC5cbiAgICogQHJldHVybnMgQSBuZXcge0BsaW5rIEkyNTZCdWlsZGVyfSBpbnN0YW5jZVxuICAgKi9cbiAgaTI1NjogKCkgPT4gbmV3IEkyNTZCdWlsZGVyKCksXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IGBVMjU2YCB7QGxpbmsgQWxnZWJyYWljVHlwZX0gdG8gYmUgdXNlZCBpbiB0YWJsZSBkZWZpbml0aW9uc1xuICAgKiBSZXByZXNlbnRlZCBhcyBgYmlnaW50YCBpbiBUeXBlU2NyaXB0LlxuICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgVTI1NkJ1aWxkZXJ9IGluc3RhbmNlXG4gICAqL1xuICB1MjU2OiAoKSA9PiBuZXcgVTI1NkJ1aWxkZXIoKSxcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgYEYzMmAge0BsaW5rIEFsZ2VicmFpY1R5cGV9IHRvIGJlIHVzZWQgaW4gdGFibGUgZGVmaW5pdGlvbnNcbiAgICogUmVwcmVzZW50ZWQgYXMgYG51bWJlcmAgaW4gVHlwZVNjcmlwdC5cbiAgICogQHJldHVybnMgQSBuZXcge0BsaW5rIEYzMkJ1aWxkZXJ9IGluc3RhbmNlXG4gICAqL1xuICBmMzI6ICgpID0+IG5ldyBGMzJCdWlsZGVyKCksXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IGBGNjRgIHtAbGluayBBbGdlYnJhaWNUeXBlfSB0byBiZSB1c2VkIGluIHRhYmxlIGRlZmluaXRpb25zXG4gICAqIFJlcHJlc2VudGVkIGFzIGBudW1iZXJgIGluIFR5cGVTY3JpcHQuXG4gICAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBGNjRCdWlsZGVyfSBpbnN0YW5jZVxuICAgKi9cbiAgZjY0OiAoKSA9PiBuZXcgRjY0QnVpbGRlcigpLFxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBgUHJvZHVjdGAge0BsaW5rIEFsZ2VicmFpY1R5cGV9IHRvIGJlIHVzZWQgaW4gdGFibGUgZGVmaW5pdGlvbnMuIFByb2R1Y3QgdHlwZXMgaW4gU3BhY2V0aW1lREJcbiAgICogYXJlIGVzc2VudGlhbGx5IHRoZSBzYW1lIGFzIG9iamVjdHMgaW4gSmF2YVNjcmlwdC9UeXBlU2NyaXB0LlxuICAgKiBQcm9wZXJ0aWVzIG9mIHRoZSBvYmplY3QgbXVzdCBhbHNvIGJlIHtAbGluayBUeXBlQnVpbGRlcn1zLlxuICAgKiBSZXByZXNlbnRlZCBhcyBhbiBvYmplY3Qgd2l0aCBzcGVjaWZpYyBwcm9wZXJ0aWVzIGluIFR5cGVTY3JpcHQuXG4gICAqXG4gICAqIEBwYXJhbSBuYW1lIChvcHRpb25hbCkgQSBkaXNwbGF5IG5hbWUgZm9yIHRoZSBwcm9kdWN0IHR5cGUuIElmIG9taXR0ZWQsIGFuIGFub255bW91cyBwcm9kdWN0IHR5cGUgaXMgY3JlYXRlZC5cbiAgICogQHBhcmFtIG9iaiBUaGUgb2JqZWN0IGRlZmluaW5nIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSB0eXBlLCB3aG9zZSBwcm9wZXJ0eVxuICAgKiB2YWx1ZXMgbXVzdCBiZSB7QGxpbmsgVHlwZUJ1aWxkZXJ9cy5cbiAgICogQHJldHVybnMgQSBuZXcge0BsaW5rIFByb2R1Y3RCdWlsZGVyfSBpbnN0YW5jZS5cbiAgICovXG4gIG9iamVjdDogKChuYW1lT3JPYmosIG1heWJlT2JqKSA9PiB7XG4gICAgaWYgKHR5cGVvZiBuYW1lT3JPYmogPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIGlmICghbWF5YmVPYmopIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICBcIldoZW4gcHJvdmlkaW5nIGEgbmFtZSwgeW91IG11c3QgYWxzbyBwcm92aWRlIHRoZSBvYmplY3QuXCJcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgUHJvZHVjdEJ1aWxkZXIobWF5YmVPYmosIG5hbWVPck9iaik7XG4gICAgfVxuICAgIHJldHVybiBuZXcgUHJvZHVjdEJ1aWxkZXIobmFtZU9yT2JqLCB2b2lkIDApO1xuICB9KSxcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgYFJvd2Age0BsaW5rIEFsZ2VicmFpY1R5cGV9IHRvIGJlIHVzZWQgaW4gdGFibGUgZGVmaW5pdGlvbnMuIFJvdyB0eXBlcyBpbiBTcGFjZXRpbWVEQlxuICAgKiBhcmUgc2ltaWxhciB0byBgUHJvZHVjdGAgdHlwZXMsIGJ1dCBhcmUgc3BlY2lmaWNhbGx5IHVzZWQgdG8gZGVmaW5lIHRoZSBzY2hlbWEgb2YgYSB0YWJsZSByb3cuXG4gICAqIFByb3BlcnRpZXMgb2YgdGhlIG9iamVjdCBtdXN0IGFsc28gYmUge0BsaW5rIFR5cGVCdWlsZGVyfSBvciB7QGxpbmsgQ29sdW1uQnVpbGRlcn1zLlxuICAgKlxuICAgKiBZb3UgY2FuIHJlcHJlc2VudCBhIGBSb3dgIGFzIGVpdGhlciBhIHtAbGluayBSb3dPYmp9IG9yIGFuIHtAbGluayBSb3dCdWlsZGVyfSB0eXBlIHdoZW5cbiAgICogZGVmaW5pbmcgYSB0YWJsZSBzY2hlbWEuXG4gICAqXG4gICAqIFRoZSB7QGxpbmsgUm93QnVpbGRlcn0gdHlwZSBpcyB1c2VmdWwgd2hlbiB5b3Ugd2FudCB0byBjcmVhdGUgYSB0eXBlIHdoaWNoIGNhbiBiZSB1c2VkIGFueXdoZXJlXG4gICAqIGEge0BsaW5rIFR5cGVCdWlsZGVyfSBpcyBhY2NlcHRlZCwgc3VjaCBhcyBpbiBuZXN0ZWQgb2JqZWN0cyBvciBhcnJheXMsIG9yIGFzIHRoZSBhcmd1bWVudFxuICAgKiB0byBhIHNjaGVkdWxlZCBmdW5jdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIG9iaiBUaGUgb2JqZWN0IGRlZmluaW5nIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSByb3csIHdob3NlIHByb3BlcnR5XG4gICAqIHZhbHVlcyBtdXN0IGJlIHtAbGluayBUeXBlQnVpbGRlcn1zIG9yIHtAbGluayBDb2x1bW5CdWlsZGVyfXMuXG4gICAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBSb3dCdWlsZGVyfSBpbnN0YW5jZVxuICAgKi9cbiAgcm93OiAoKG5hbWVPck9iaiwgbWF5YmVPYmopID0+IHtcbiAgICBjb25zdCBbb2JqLCBuYW1lXSA9IHR5cGVvZiBuYW1lT3JPYmogPT09IFwic3RyaW5nXCIgPyBbbWF5YmVPYmosIG5hbWVPck9ial0gOiBbbmFtZU9yT2JqLCB2b2lkIDBdO1xuICAgIHJldHVybiBuZXcgUm93QnVpbGRlcihvYmosIG5hbWUpO1xuICB9KSxcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgYEFycmF5YCB7QGxpbmsgQWxnZWJyYWljVHlwZX0gdG8gYmUgdXNlZCBpbiB0YWJsZSBkZWZpbml0aW9ucy5cbiAgICogUmVwcmVzZW50ZWQgYXMgYW4gYXJyYXkgaW4gVHlwZVNjcmlwdC5cbiAgICogQHBhcmFtIGVsZW1lbnQgVGhlIGVsZW1lbnQgdHlwZSBvZiB0aGUgYXJyYXksIHdoaWNoIG11c3QgYmUgYSBgVHlwZUJ1aWxkZXJgLlxuICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgQXJyYXlCdWlsZGVyfSBpbnN0YW5jZVxuICAgKi9cbiAgYXJyYXkoZSkge1xuICAgIHJldHVybiBuZXcgQXJyYXlCdWlsZGVyKGUpO1xuICB9LFxuICBlbnVtOiBlbnVtSW1wbCxcbiAgLyoqXG4gICAqIFRoaXMgaXMgYSBzcGVjaWFsIGhlbHBlciBmdW5jdGlvbiBmb3IgY29udmVuaWVudGx5IGNyZWF0aW5nIGBQcm9kdWN0YCB0eXBlIGNvbHVtbnMgd2l0aCBubyBmaWVsZHMuXG4gICAqXG4gICAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBQcm9kdWN0QnVpbGRlcn0gaW5zdGFuY2Ugd2l0aCBubyBmaWVsZHMuXG4gICAqL1xuICB1bml0KCkge1xuICAgIHJldHVybiBuZXcgVW5pdEJ1aWxkZXIoKTtcbiAgfSxcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBsYXppbHktZXZhbHVhdGVkIHtAbGluayBUeXBlQnVpbGRlcn0uIFRoaXMgaXMgdXNlZnVsIGZvciBjcmVhdGluZ1xuICAgKiByZWN1cnNpdmUgdHlwZXMsIHN1Y2ggYXMgYSB0cmVlIG9yIGxpbmtlZCBsaXN0LlxuICAgKiBAcGFyYW0gdGh1bmsgQSBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSB7QGxpbmsgVHlwZUJ1aWxkZXJ9LlxuICAgKiBAcmV0dXJucyBBIHByb3h5IHtAbGluayBUeXBlQnVpbGRlcn0gdGhhdCBldmFsdWF0ZXMgdGhlIHRodW5rIG9uIGZpcnN0IGFjY2Vzcy5cbiAgICovXG4gIGxhenkodGh1bmspIHtcbiAgICBsZXQgY2FjaGVkID0gbnVsbDtcbiAgICBjb25zdCBnZXQgPSAoKSA9PiBjYWNoZWQgPz89IHRodW5rKCk7XG4gICAgY29uc3QgcHJveHkgPSBuZXcgUHJveHkoe30sIHtcbiAgICAgIGdldChfdCwgcHJvcCwgcmVjdikge1xuICAgICAgICBjb25zdCB0YXJnZXQgPSBnZXQoKTtcbiAgICAgICAgY29uc3QgdmFsID0gUmVmbGVjdC5nZXQodGFyZ2V0LCBwcm9wLCByZWN2KTtcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB2YWwgPT09IFwiZnVuY3Rpb25cIiA/IHZhbC5iaW5kKHRhcmdldCkgOiB2YWw7XG4gICAgICB9LFxuICAgICAgc2V0KF90LCBwcm9wLCB2YWx1ZSwgcmVjdikge1xuICAgICAgICByZXR1cm4gUmVmbGVjdC5zZXQoZ2V0KCksIHByb3AsIHZhbHVlLCByZWN2KTtcbiAgICAgIH0sXG4gICAgICBoYXMoX3QsIHByb3ApIHtcbiAgICAgICAgcmV0dXJuIHByb3AgaW4gZ2V0KCk7XG4gICAgICB9LFxuICAgICAgb3duS2V5cygpIHtcbiAgICAgICAgcmV0dXJuIFJlZmxlY3Qub3duS2V5cyhnZXQoKSk7XG4gICAgICB9LFxuICAgICAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF90LCBwcm9wKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGdldCgpLCBwcm9wKTtcbiAgICAgIH0sXG4gICAgICBnZXRQcm90b3R5cGVPZigpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5nZXRQcm90b3R5cGVPZihnZXQoKSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHByb3h5O1xuICB9LFxuICAvKipcbiAgICogVGhpcyBpcyBhIHNwZWNpYWwgaGVscGVyIGZ1bmN0aW9uIGZvciBjb252ZW5pZW50bHkgY3JlYXRpbmcge0BsaW5rIFNjaGVkdWxlQXR9IHR5cGUgY29sdW1ucy5cbiAgICogQHJldHVybnMgQSBuZXcgQ29sdW1uQnVpbGRlciBpbnN0YW5jZSB3aXRoIHRoZSB7QGxpbmsgU2NoZWR1bGVBdH0gdHlwZS5cbiAgICovXG4gIHNjaGVkdWxlQXQ6ICgpID0+IHtcbiAgICByZXR1cm4gbmV3IFNjaGVkdWxlQXRCdWlsZGVyKCk7XG4gIH0sXG4gIC8qKlxuICAgKiBUaGlzIGlzIGEgY29udmVuaWVuY2UgbWV0aG9kIGZvciBjcmVhdGluZyBhIGNvbHVtbiB3aXRoIHRoZSB7QGxpbmsgT3B0aW9ufSB0eXBlLlxuICAgKiBZb3UgY2FuIGNyZWF0ZSBhIGNvbHVtbiBvZiB0aGUgc2FtZSB0eXBlIGJ5IGNvbnN0cnVjdGluZyBhbiBlbnVtIHdpdGggYSBgc29tZWAgYW5kIGBub25lYCB2YXJpYW50LlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHR5cGUgb2YgdGhlIHZhbHVlIGNvbnRhaW5lZCBpbiB0aGUgYHNvbWVgIHZhcmlhbnQgb2YgdGhlIGBPcHRpb25gLlxuICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgT3B0aW9uQnVpbGRlcn0gaW5zdGFuY2Ugd2l0aCB0aGUge0BsaW5rIE9wdGlvbn0gdHlwZS5cbiAgICovXG4gIG9wdGlvbih2YWx1ZSkge1xuICAgIHJldHVybiBuZXcgT3B0aW9uQnVpbGRlcih2YWx1ZSk7XG4gIH0sXG4gIC8qKlxuICAgKiBUaGlzIGlzIGEgY29udmVuaWVuY2UgbWV0aG9kIGZvciBjcmVhdGluZyBhIGNvbHVtbiB3aXRoIHRoZSB7QGxpbmsgUmVzdWx0fSB0eXBlLlxuICAgKiBZb3UgY2FuIGNyZWF0ZSBhIGNvbHVtbiBvZiB0aGUgc2FtZSB0eXBlIGJ5IGNvbnN0cnVjdGluZyBhbiBlbnVtIHdpdGggYW4gYG9rYCBhbmQgYGVycmAgdmFyaWFudC5cbiAgICogQHBhcmFtIG9rIFRoZSB0eXBlIG9mIHRoZSB2YWx1ZSBjb250YWluZWQgaW4gdGhlIGBva2AgdmFyaWFudCBvZiB0aGUgYFJlc3VsdGAuXG4gICAqIEBwYXJhbSBlcnIgVGhlIHR5cGUgb2YgdGhlIHZhbHVlIGNvbnRhaW5lZCBpbiB0aGUgYGVycmAgdmFyaWFudCBvZiB0aGUgYFJlc3VsdGAuXG4gICAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBSZXN1bHRCdWlsZGVyfSBpbnN0YW5jZSB3aXRoIHRoZSB7QGxpbmsgUmVzdWx0fSB0eXBlLlxuICAgKi9cbiAgcmVzdWx0KG9rLCBlcnIpIHtcbiAgICByZXR1cm4gbmV3IFJlc3VsdEJ1aWxkZXIob2ssIGVycik7XG4gIH0sXG4gIC8qKlxuICAgKiBUaGlzIGlzIGEgY29udmVuaWVuY2UgbWV0aG9kIGZvciBjcmVhdGluZyBhIGNvbHVtbiB3aXRoIHRoZSB7QGxpbmsgSWRlbnRpdHl9IHR5cGUuXG4gICAqIFlvdSBjYW4gY3JlYXRlIGEgY29sdW1uIG9mIHRoZSBzYW1lIHR5cGUgYnkgY29uc3RydWN0aW5nIGFuIGBvYmplY3RgIHdpdGggYSBzaW5nbGUgYF9faWRlbnRpdHlfX2AgZWxlbWVudC5cbiAgICogQHJldHVybnMgQSBuZXcge0BsaW5rIFR5cGVCdWlsZGVyfSBpbnN0YW5jZSB3aXRoIHRoZSB7QGxpbmsgSWRlbnRpdHl9IHR5cGUuXG4gICAqL1xuICBpZGVudGl0eTogKCkgPT4ge1xuICAgIHJldHVybiBuZXcgSWRlbnRpdHlCdWlsZGVyKCk7XG4gIH0sXG4gIC8qKlxuICAgKiBUaGlzIGlzIGEgY29udmVuaWVuY2UgbWV0aG9kIGZvciBjcmVhdGluZyBhIGNvbHVtbiB3aXRoIHRoZSB7QGxpbmsgQ29ubmVjdGlvbklkfSB0eXBlLlxuICAgKiBZb3UgY2FuIGNyZWF0ZSBhIGNvbHVtbiBvZiB0aGUgc2FtZSB0eXBlIGJ5IGNvbnN0cnVjdGluZyBhbiBgb2JqZWN0YCB3aXRoIGEgc2luZ2xlIGBfX2Nvbm5lY3Rpb25faWRfX2AgZWxlbWVudC5cbiAgICogQHJldHVybnMgQSBuZXcge0BsaW5rIFR5cGVCdWlsZGVyfSBpbnN0YW5jZSB3aXRoIHRoZSB7QGxpbmsgQ29ubmVjdGlvbklkfSB0eXBlLlxuICAgKi9cbiAgY29ubmVjdGlvbklkOiAoKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBDb25uZWN0aW9uSWRCdWlsZGVyKCk7XG4gIH0sXG4gIC8qKlxuICAgKiBUaGlzIGlzIGEgY29udmVuaWVuY2UgbWV0aG9kIGZvciBjcmVhdGluZyBhIGNvbHVtbiB3aXRoIHRoZSB7QGxpbmsgVGltZXN0YW1wfSB0eXBlLlxuICAgKiBZb3UgY2FuIGNyZWF0ZSBhIGNvbHVtbiBvZiB0aGUgc2FtZSB0eXBlIGJ5IGNvbnN0cnVjdGluZyBhbiBgb2JqZWN0YCB3aXRoIGEgc2luZ2xlIGBfX3RpbWVzdGFtcF9taWNyb3Nfc2luY2VfdW5peF9lcG9jaF9fYCBlbGVtZW50LlxuICAgKiBAcmV0dXJucyBBIG5ldyB7QGxpbmsgVHlwZUJ1aWxkZXJ9IGluc3RhbmNlIHdpdGggdGhlIHtAbGluayBUaW1lc3RhbXB9IHR5cGUuXG4gICAqL1xuICB0aW1lc3RhbXA6ICgpID0+IHtcbiAgICByZXR1cm4gbmV3IFRpbWVzdGFtcEJ1aWxkZXIoKTtcbiAgfSxcbiAgLyoqXG4gICAqIFRoaXMgaXMgYSBjb252ZW5pZW5jZSBtZXRob2QgZm9yIGNyZWF0aW5nIGEgY29sdW1uIHdpdGggdGhlIHtAbGluayBUaW1lRHVyYXRpb259IHR5cGUuXG4gICAqIFlvdSBjYW4gY3JlYXRlIGEgY29sdW1uIG9mIHRoZSBzYW1lIHR5cGUgYnkgY29uc3RydWN0aW5nIGFuIGBvYmplY3RgIHdpdGggYSBzaW5nbGUgYF9fdGltZV9kdXJhdGlvbl9taWNyb3NfX2AgZWxlbWVudC5cbiAgICogQHJldHVybnMgQSBuZXcge0BsaW5rIFR5cGVCdWlsZGVyfSBpbnN0YW5jZSB3aXRoIHRoZSB7QGxpbmsgVGltZUR1cmF0aW9ufSB0eXBlLlxuICAgKi9cbiAgdGltZUR1cmF0aW9uOiAoKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBUaW1lRHVyYXRpb25CdWlsZGVyKCk7XG4gIH0sXG4gIC8qKlxuICAgKiBUaGlzIGlzIGEgY29udmVuaWVuY2UgbWV0aG9kIGZvciBjcmVhdGluZyBhIGNvbHVtbiB3aXRoIHRoZSB7QGxpbmsgVXVpZH0gdHlwZS5cbiAgICogWW91IGNhbiBjcmVhdGUgYSBjb2x1bW4gb2YgdGhlIHNhbWUgdHlwZSBieSBjb25zdHJ1Y3RpbmcgYW4gYG9iamVjdGAgd2l0aCBhIHNpbmdsZSBgX191dWlkX19gIGVsZW1lbnQuXG4gICAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBUeXBlQnVpbGRlcn0gaW5zdGFuY2Ugd2l0aCB0aGUge0BsaW5rIFV1aWR9IHR5cGUuXG4gICAqL1xuICB1dWlkOiAoKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBVdWlkQnVpbGRlcigpO1xuICB9LFxuICAvKipcbiAgICogVGhpcyBpcyBhIGNvbnZlbmllbmNlIG1ldGhvZCBmb3IgY3JlYXRpbmcgYSBjb2x1bW4gd2l0aCB0aGUgYEJ5dGVBcnJheWAgdHlwZS5cbiAgICogWW91IGNhbiBjcmVhdGUgYSBjb2x1bW4gb2YgdGhlIHNhbWUgdHlwZSBieSBjb25zdHJ1Y3RpbmcgYW4gYGFycmF5YCBvZiBgdThgLlxuICAgKiBUaGUgVHlwZVNjcmlwdCByZXByZXNlbnRhdGlvbiBpcyB7QGxpbmsgVWludDhBcnJheX0uXG4gICAqIEByZXR1cm5zIEEgbmV3IHtAbGluayBCeXRlQXJyYXlCdWlsZGVyfSBpbnN0YW5jZSB3aXRoIHRoZSBgQnl0ZUFycmF5YCB0eXBlLlxuICAgKi9cbiAgYnl0ZUFycmF5OiAoKSA9PiB7XG4gICAgcmV0dXJuIG5ldyBCeXRlQXJyYXlCdWlsZGVyKCk7XG4gIH1cbn07XG5cbi8vIHNyYy9saWIvYXV0b2dlbi90eXBlcy50c1xudmFyIEFsZ2VicmFpY1R5cGUyID0gdC5lbnVtKFwiQWxnZWJyYWljVHlwZVwiLCB7XG4gIFJlZjogdC51MzIoKSxcbiAgZ2V0IFN1bSgpIHtcbiAgICByZXR1cm4gU3VtVHlwZTI7XG4gIH0sXG4gIGdldCBQcm9kdWN0KCkge1xuICAgIHJldHVybiBQcm9kdWN0VHlwZTI7XG4gIH0sXG4gIGdldCBBcnJheSgpIHtcbiAgICByZXR1cm4gQWxnZWJyYWljVHlwZTI7XG4gIH0sXG4gIFN0cmluZzogdC51bml0KCksXG4gIEJvb2w6IHQudW5pdCgpLFxuICBJODogdC51bml0KCksXG4gIFU4OiB0LnVuaXQoKSxcbiAgSTE2OiB0LnVuaXQoKSxcbiAgVTE2OiB0LnVuaXQoKSxcbiAgSTMyOiB0LnVuaXQoKSxcbiAgVTMyOiB0LnVuaXQoKSxcbiAgSTY0OiB0LnVuaXQoKSxcbiAgVTY0OiB0LnVuaXQoKSxcbiAgSTEyODogdC51bml0KCksXG4gIFUxMjg6IHQudW5pdCgpLFxuICBJMjU2OiB0LnVuaXQoKSxcbiAgVTI1NjogdC51bml0KCksXG4gIEYzMjogdC51bml0KCksXG4gIEY2NDogdC51bml0KClcbn0pO1xudmFyIENhc2VDb252ZXJzaW9uUG9saWN5ID0gdC5lbnVtKFwiQ2FzZUNvbnZlcnNpb25Qb2xpY3lcIiwge1xuICBOb25lOiB0LnVuaXQoKSxcbiAgU25ha2VDYXNlOiB0LnVuaXQoKVxufSk7XG52YXIgRXhwbGljaXROYW1lRW50cnkgPSB0LmVudW0oXCJFeHBsaWNpdE5hbWVFbnRyeVwiLCB7XG4gIGdldCBUYWJsZSgpIHtcbiAgICByZXR1cm4gTmFtZU1hcHBpbmc7XG4gIH0sXG4gIGdldCBGdW5jdGlvbigpIHtcbiAgICByZXR1cm4gTmFtZU1hcHBpbmc7XG4gIH0sXG4gIGdldCBJbmRleCgpIHtcbiAgICByZXR1cm4gTmFtZU1hcHBpbmc7XG4gIH1cbn0pO1xudmFyIEV4cGxpY2l0TmFtZXMgPSB0Lm9iamVjdChcIkV4cGxpY2l0TmFtZXNcIiwge1xuICBnZXQgZW50cmllcygpIHtcbiAgICByZXR1cm4gdC5hcnJheShFeHBsaWNpdE5hbWVFbnRyeSk7XG4gIH1cbn0pO1xudmFyIEZ1bmN0aW9uVmlzaWJpbGl0eSA9IHQuZW51bShcIkZ1bmN0aW9uVmlzaWJpbGl0eVwiLCB7XG4gIFByaXZhdGU6IHQudW5pdCgpLFxuICBDbGllbnRDYWxsYWJsZTogdC51bml0KClcbn0pO1xudmFyIEh0dHBIZWFkZXJQYWlyID0gdC5vYmplY3QoXCJIdHRwSGVhZGVyUGFpclwiLCB7XG4gIG5hbWU6IHQuc3RyaW5nKCksXG4gIHZhbHVlOiB0LmJ5dGVBcnJheSgpXG59KTtcbnZhciBIdHRwSGVhZGVycyA9IHQub2JqZWN0KFwiSHR0cEhlYWRlcnNcIiwge1xuICBnZXQgZW50cmllcygpIHtcbiAgICByZXR1cm4gdC5hcnJheShIdHRwSGVhZGVyUGFpcik7XG4gIH1cbn0pO1xudmFyIEh0dHBNZXRob2QgPSB0LmVudW0oXCJIdHRwTWV0aG9kXCIsIHtcbiAgR2V0OiB0LnVuaXQoKSxcbiAgSGVhZDogdC51bml0KCksXG4gIFBvc3Q6IHQudW5pdCgpLFxuICBQdXQ6IHQudW5pdCgpLFxuICBEZWxldGU6IHQudW5pdCgpLFxuICBDb25uZWN0OiB0LnVuaXQoKSxcbiAgT3B0aW9uczogdC51bml0KCksXG4gIFRyYWNlOiB0LnVuaXQoKSxcbiAgUGF0Y2g6IHQudW5pdCgpLFxuICBFeHRlbnNpb246IHQuc3RyaW5nKClcbn0pO1xudmFyIEh0dHBSZXF1ZXN0ID0gdC5vYmplY3QoXCJIdHRwUmVxdWVzdFwiLCB7XG4gIGdldCBtZXRob2QoKSB7XG4gICAgcmV0dXJuIEh0dHBNZXRob2Q7XG4gIH0sXG4gIGdldCBoZWFkZXJzKCkge1xuICAgIHJldHVybiBIdHRwSGVhZGVycztcbiAgfSxcbiAgdGltZW91dDogdC5vcHRpb24odC50aW1lRHVyYXRpb24oKSksXG4gIHVyaTogdC5zdHJpbmcoKSxcbiAgZ2V0IHZlcnNpb24oKSB7XG4gICAgcmV0dXJuIEh0dHBWZXJzaW9uO1xuICB9XG59KTtcbnZhciBIdHRwUmVzcG9uc2UgPSB0Lm9iamVjdChcIkh0dHBSZXNwb25zZVwiLCB7XG4gIGdldCBoZWFkZXJzKCkge1xuICAgIHJldHVybiBIdHRwSGVhZGVycztcbiAgfSxcbiAgZ2V0IHZlcnNpb24oKSB7XG4gICAgcmV0dXJuIEh0dHBWZXJzaW9uO1xuICB9LFxuICBjb2RlOiB0LnUxNigpXG59KTtcbnZhciBIdHRwVmVyc2lvbiA9IHQuZW51bShcIkh0dHBWZXJzaW9uXCIsIHtcbiAgSHR0cDA5OiB0LnVuaXQoKSxcbiAgSHR0cDEwOiB0LnVuaXQoKSxcbiAgSHR0cDExOiB0LnVuaXQoKSxcbiAgSHR0cDI6IHQudW5pdCgpLFxuICBIdHRwMzogdC51bml0KClcbn0pO1xudmFyIEluZGV4VHlwZSA9IHQuZW51bShcIkluZGV4VHlwZVwiLCB7XG4gIEJUcmVlOiB0LnVuaXQoKSxcbiAgSGFzaDogdC51bml0KClcbn0pO1xudmFyIExpZmVjeWNsZSA9IHQuZW51bShcIkxpZmVjeWNsZVwiLCB7XG4gIEluaXQ6IHQudW5pdCgpLFxuICBPbkNvbm5lY3Q6IHQudW5pdCgpLFxuICBPbkRpc2Nvbm5lY3Q6IHQudW5pdCgpXG59KTtcbnZhciBNaXNjTW9kdWxlRXhwb3J0ID0gdC5lbnVtKFwiTWlzY01vZHVsZUV4cG9ydFwiLCB7XG4gIGdldCBUeXBlQWxpYXMoKSB7XG4gICAgcmV0dXJuIFR5cGVBbGlhcztcbiAgfVxufSk7XG52YXIgTmFtZU1hcHBpbmcgPSB0Lm9iamVjdChcIk5hbWVNYXBwaW5nXCIsIHtcbiAgc291cmNlTmFtZTogdC5zdHJpbmcoKSxcbiAgY2Fub25pY2FsTmFtZTogdC5zdHJpbmcoKVxufSk7XG52YXIgUHJvZHVjdFR5cGUyID0gdC5vYmplY3QoXCJQcm9kdWN0VHlwZVwiLCB7XG4gIGdldCBlbGVtZW50cygpIHtcbiAgICByZXR1cm4gdC5hcnJheShQcm9kdWN0VHlwZUVsZW1lbnQpO1xuICB9XG59KTtcbnZhciBQcm9kdWN0VHlwZUVsZW1lbnQgPSB0Lm9iamVjdChcIlByb2R1Y3RUeXBlRWxlbWVudFwiLCB7XG4gIG5hbWU6IHQub3B0aW9uKHQuc3RyaW5nKCkpLFxuICBnZXQgYWxnZWJyYWljVHlwZSgpIHtcbiAgICByZXR1cm4gQWxnZWJyYWljVHlwZTI7XG4gIH1cbn0pO1xudmFyIFJhd0NvbHVtbkRlZlY4ID0gdC5vYmplY3QoXCJSYXdDb2x1bW5EZWZWOFwiLCB7XG4gIGNvbE5hbWU6IHQuc3RyaW5nKCksXG4gIGdldCBjb2xUeXBlKCkge1xuICAgIHJldHVybiBBbGdlYnJhaWNUeXBlMjtcbiAgfVxufSk7XG52YXIgUmF3Q29sdW1uRGVmYXVsdFZhbHVlVjEwID0gdC5vYmplY3QoXCJSYXdDb2x1bW5EZWZhdWx0VmFsdWVWMTBcIiwge1xuICBjb2xJZDogdC51MTYoKSxcbiAgdmFsdWU6IHQuYnl0ZUFycmF5KClcbn0pO1xudmFyIFJhd0NvbHVtbkRlZmF1bHRWYWx1ZVY5ID0gdC5vYmplY3QoXCJSYXdDb2x1bW5EZWZhdWx0VmFsdWVWOVwiLCB7XG4gIHRhYmxlOiB0LnN0cmluZygpLFxuICBjb2xJZDogdC51MTYoKSxcbiAgdmFsdWU6IHQuYnl0ZUFycmF5KClcbn0pO1xudmFyIFJhd0NvbnN0cmFpbnREYXRhVjkgPSB0LmVudW0oXCJSYXdDb25zdHJhaW50RGF0YVY5XCIsIHtcbiAgZ2V0IFVuaXF1ZSgpIHtcbiAgICByZXR1cm4gUmF3VW5pcXVlQ29uc3RyYWludERhdGFWOTtcbiAgfVxufSk7XG52YXIgUmF3Q29uc3RyYWludERlZlYxMCA9IHQub2JqZWN0KFwiUmF3Q29uc3RyYWludERlZlYxMFwiLCB7XG4gIHNvdXJjZU5hbWU6IHQub3B0aW9uKHQuc3RyaW5nKCkpLFxuICBnZXQgZGF0YSgpIHtcbiAgICByZXR1cm4gUmF3Q29uc3RyYWludERhdGFWOTtcbiAgfVxufSk7XG52YXIgUmF3Q29uc3RyYWludERlZlY4ID0gdC5vYmplY3QoXCJSYXdDb25zdHJhaW50RGVmVjhcIiwge1xuICBjb25zdHJhaW50TmFtZTogdC5zdHJpbmcoKSxcbiAgY29uc3RyYWludHM6IHQudTgoKSxcbiAgY29sdW1uczogdC5hcnJheSh0LnUxNigpKVxufSk7XG52YXIgUmF3Q29uc3RyYWludERlZlY5ID0gdC5vYmplY3QoXCJSYXdDb25zdHJhaW50RGVmVjlcIiwge1xuICBuYW1lOiB0Lm9wdGlvbih0LnN0cmluZygpKSxcbiAgZ2V0IGRhdGEoKSB7XG4gICAgcmV0dXJuIFJhd0NvbnN0cmFpbnREYXRhVjk7XG4gIH1cbn0pO1xudmFyIFJhd0luZGV4QWxnb3JpdGhtID0gdC5lbnVtKFwiUmF3SW5kZXhBbGdvcml0aG1cIiwge1xuICBCVHJlZTogdC5hcnJheSh0LnUxNigpKSxcbiAgSGFzaDogdC5hcnJheSh0LnUxNigpKSxcbiAgRGlyZWN0OiB0LnUxNigpXG59KTtcbnZhciBSYXdJbmRleERlZlYxMCA9IHQub2JqZWN0KFwiUmF3SW5kZXhEZWZWMTBcIiwge1xuICBzb3VyY2VOYW1lOiB0Lm9wdGlvbih0LnN0cmluZygpKSxcbiAgYWNjZXNzb3JOYW1lOiB0Lm9wdGlvbih0LnN0cmluZygpKSxcbiAgZ2V0IGFsZ29yaXRobSgpIHtcbiAgICByZXR1cm4gUmF3SW5kZXhBbGdvcml0aG07XG4gIH1cbn0pO1xudmFyIFJhd0luZGV4RGVmVjggPSB0Lm9iamVjdChcIlJhd0luZGV4RGVmVjhcIiwge1xuICBpbmRleE5hbWU6IHQuc3RyaW5nKCksXG4gIGlzVW5pcXVlOiB0LmJvb2woKSxcbiAgZ2V0IGluZGV4VHlwZSgpIHtcbiAgICByZXR1cm4gSW5kZXhUeXBlO1xuICB9LFxuICBjb2x1bW5zOiB0LmFycmF5KHQudTE2KCkpXG59KTtcbnZhciBSYXdJbmRleERlZlY5ID0gdC5vYmplY3QoXCJSYXdJbmRleERlZlY5XCIsIHtcbiAgbmFtZTogdC5vcHRpb24odC5zdHJpbmcoKSksXG4gIGFjY2Vzc29yTmFtZTogdC5vcHRpb24odC5zdHJpbmcoKSksXG4gIGdldCBhbGdvcml0aG0oKSB7XG4gICAgcmV0dXJuIFJhd0luZGV4QWxnb3JpdGhtO1xuICB9XG59KTtcbnZhciBSYXdMaWZlQ3ljbGVSZWR1Y2VyRGVmVjEwID0gdC5vYmplY3QoXG4gIFwiUmF3TGlmZUN5Y2xlUmVkdWNlckRlZlYxMFwiLFxuICB7XG4gICAgZ2V0IGxpZmVjeWNsZVNwZWMoKSB7XG4gICAgICByZXR1cm4gTGlmZWN5Y2xlO1xuICAgIH0sXG4gICAgZnVuY3Rpb25OYW1lOiB0LnN0cmluZygpXG4gIH1cbik7XG52YXIgUmF3TWlzY01vZHVsZUV4cG9ydFY5ID0gdC5lbnVtKFwiUmF3TWlzY01vZHVsZUV4cG9ydFY5XCIsIHtcbiAgZ2V0IENvbHVtbkRlZmF1bHRWYWx1ZSgpIHtcbiAgICByZXR1cm4gUmF3Q29sdW1uRGVmYXVsdFZhbHVlVjk7XG4gIH0sXG4gIGdldCBQcm9jZWR1cmUoKSB7XG4gICAgcmV0dXJuIFJhd1Byb2NlZHVyZURlZlY5O1xuICB9LFxuICBnZXQgVmlldygpIHtcbiAgICByZXR1cm4gUmF3Vmlld0RlZlY5O1xuICB9XG59KTtcbnZhciBSYXdNb2R1bGVEZWYgPSB0LmVudW0oXCJSYXdNb2R1bGVEZWZcIiwge1xuICBnZXQgVjhCYWNrQ29tcGF0KCkge1xuICAgIHJldHVybiBSYXdNb2R1bGVEZWZWODtcbiAgfSxcbiAgZ2V0IFY5KCkge1xuICAgIHJldHVybiBSYXdNb2R1bGVEZWZWOTtcbiAgfSxcbiAgZ2V0IFYxMCgpIHtcbiAgICByZXR1cm4gUmF3TW9kdWxlRGVmVjEwO1xuICB9XG59KTtcbnZhciBSYXdNb2R1bGVEZWZWMTAgPSB0Lm9iamVjdChcIlJhd01vZHVsZURlZlYxMFwiLCB7XG4gIGdldCBzZWN0aW9ucygpIHtcbiAgICByZXR1cm4gdC5hcnJheShSYXdNb2R1bGVEZWZWMTBTZWN0aW9uKTtcbiAgfVxufSk7XG52YXIgUmF3TW9kdWxlRGVmVjEwU2VjdGlvbiA9IHQuZW51bShcIlJhd01vZHVsZURlZlYxMFNlY3Rpb25cIiwge1xuICBnZXQgVHlwZXNwYWNlKCkge1xuICAgIHJldHVybiBUeXBlc3BhY2U7XG4gIH0sXG4gIGdldCBUeXBlcygpIHtcbiAgICByZXR1cm4gdC5hcnJheShSYXdUeXBlRGVmVjEwKTtcbiAgfSxcbiAgZ2V0IFRhYmxlcygpIHtcbiAgICByZXR1cm4gdC5hcnJheShSYXdUYWJsZURlZlYxMCk7XG4gIH0sXG4gIGdldCBSZWR1Y2VycygpIHtcbiAgICByZXR1cm4gdC5hcnJheShSYXdSZWR1Y2VyRGVmVjEwKTtcbiAgfSxcbiAgZ2V0IFByb2NlZHVyZXMoKSB7XG4gICAgcmV0dXJuIHQuYXJyYXkoUmF3UHJvY2VkdXJlRGVmVjEwKTtcbiAgfSxcbiAgZ2V0IFZpZXdzKCkge1xuICAgIHJldHVybiB0LmFycmF5KFJhd1ZpZXdEZWZWMTApO1xuICB9LFxuICBnZXQgU2NoZWR1bGVzKCkge1xuICAgIHJldHVybiB0LmFycmF5KFJhd1NjaGVkdWxlRGVmVjEwKTtcbiAgfSxcbiAgZ2V0IExpZmVDeWNsZVJlZHVjZXJzKCkge1xuICAgIHJldHVybiB0LmFycmF5KFJhd0xpZmVDeWNsZVJlZHVjZXJEZWZWMTApO1xuICB9LFxuICBnZXQgUm93TGV2ZWxTZWN1cml0eSgpIHtcbiAgICByZXR1cm4gdC5hcnJheShSYXdSb3dMZXZlbFNlY3VyaXR5RGVmVjkpO1xuICB9LFxuICBnZXQgQ2FzZUNvbnZlcnNpb25Qb2xpY3koKSB7XG4gICAgcmV0dXJuIENhc2VDb252ZXJzaW9uUG9saWN5O1xuICB9LFxuICBnZXQgRXhwbGljaXROYW1lcygpIHtcbiAgICByZXR1cm4gRXhwbGljaXROYW1lcztcbiAgfVxufSk7XG52YXIgUmF3TW9kdWxlRGVmVjggPSB0Lm9iamVjdChcIlJhd01vZHVsZURlZlY4XCIsIHtcbiAgZ2V0IHR5cGVzcGFjZSgpIHtcbiAgICByZXR1cm4gVHlwZXNwYWNlO1xuICB9LFxuICBnZXQgdGFibGVzKCkge1xuICAgIHJldHVybiB0LmFycmF5KFRhYmxlRGVzYyk7XG4gIH0sXG4gIGdldCByZWR1Y2VycygpIHtcbiAgICByZXR1cm4gdC5hcnJheShSZWR1Y2VyRGVmKTtcbiAgfSxcbiAgZ2V0IG1pc2NFeHBvcnRzKCkge1xuICAgIHJldHVybiB0LmFycmF5KE1pc2NNb2R1bGVFeHBvcnQpO1xuICB9XG59KTtcbnZhciBSYXdNb2R1bGVEZWZWOSA9IHQub2JqZWN0KFwiUmF3TW9kdWxlRGVmVjlcIiwge1xuICBnZXQgdHlwZXNwYWNlKCkge1xuICAgIHJldHVybiBUeXBlc3BhY2U7XG4gIH0sXG4gIGdldCB0YWJsZXMoKSB7XG4gICAgcmV0dXJuIHQuYXJyYXkoUmF3VGFibGVEZWZWOSk7XG4gIH0sXG4gIGdldCByZWR1Y2VycygpIHtcbiAgICByZXR1cm4gdC5hcnJheShSYXdSZWR1Y2VyRGVmVjkpO1xuICB9LFxuICBnZXQgdHlwZXMoKSB7XG4gICAgcmV0dXJuIHQuYXJyYXkoUmF3VHlwZURlZlY5KTtcbiAgfSxcbiAgZ2V0IG1pc2NFeHBvcnRzKCkge1xuICAgIHJldHVybiB0LmFycmF5KFJhd01pc2NNb2R1bGVFeHBvcnRWOSk7XG4gIH0sXG4gIGdldCByb3dMZXZlbFNlY3VyaXR5KCkge1xuICAgIHJldHVybiB0LmFycmF5KFJhd1Jvd0xldmVsU2VjdXJpdHlEZWZWOSk7XG4gIH1cbn0pO1xudmFyIFJhd1Byb2NlZHVyZURlZlYxMCA9IHQub2JqZWN0KFwiUmF3UHJvY2VkdXJlRGVmVjEwXCIsIHtcbiAgc291cmNlTmFtZTogdC5zdHJpbmcoKSxcbiAgZ2V0IHBhcmFtcygpIHtcbiAgICByZXR1cm4gUHJvZHVjdFR5cGUyO1xuICB9LFxuICBnZXQgcmV0dXJuVHlwZSgpIHtcbiAgICByZXR1cm4gQWxnZWJyYWljVHlwZTI7XG4gIH0sXG4gIGdldCB2aXNpYmlsaXR5KCkge1xuICAgIHJldHVybiBGdW5jdGlvblZpc2liaWxpdHk7XG4gIH1cbn0pO1xudmFyIFJhd1Byb2NlZHVyZURlZlY5ID0gdC5vYmplY3QoXCJSYXdQcm9jZWR1cmVEZWZWOVwiLCB7XG4gIG5hbWU6IHQuc3RyaW5nKCksXG4gIGdldCBwYXJhbXMoKSB7XG4gICAgcmV0dXJuIFByb2R1Y3RUeXBlMjtcbiAgfSxcbiAgZ2V0IHJldHVyblR5cGUoKSB7XG4gICAgcmV0dXJuIEFsZ2VicmFpY1R5cGUyO1xuICB9XG59KTtcbnZhciBSYXdSZWR1Y2VyRGVmVjEwID0gdC5vYmplY3QoXCJSYXdSZWR1Y2VyRGVmVjEwXCIsIHtcbiAgc291cmNlTmFtZTogdC5zdHJpbmcoKSxcbiAgZ2V0IHBhcmFtcygpIHtcbiAgICByZXR1cm4gUHJvZHVjdFR5cGUyO1xuICB9LFxuICBnZXQgdmlzaWJpbGl0eSgpIHtcbiAgICByZXR1cm4gRnVuY3Rpb25WaXNpYmlsaXR5O1xuICB9LFxuICBnZXQgb2tSZXR1cm5UeXBlKCkge1xuICAgIHJldHVybiBBbGdlYnJhaWNUeXBlMjtcbiAgfSxcbiAgZ2V0IGVyclJldHVyblR5cGUoKSB7XG4gICAgcmV0dXJuIEFsZ2VicmFpY1R5cGUyO1xuICB9XG59KTtcbnZhciBSYXdSZWR1Y2VyRGVmVjkgPSB0Lm9iamVjdChcIlJhd1JlZHVjZXJEZWZWOVwiLCB7XG4gIG5hbWU6IHQuc3RyaW5nKCksXG4gIGdldCBwYXJhbXMoKSB7XG4gICAgcmV0dXJuIFByb2R1Y3RUeXBlMjtcbiAgfSxcbiAgZ2V0IGxpZmVjeWNsZSgpIHtcbiAgICByZXR1cm4gdC5vcHRpb24oTGlmZWN5Y2xlKTtcbiAgfVxufSk7XG52YXIgUmF3Um93TGV2ZWxTZWN1cml0eURlZlY5ID0gdC5vYmplY3QoXCJSYXdSb3dMZXZlbFNlY3VyaXR5RGVmVjlcIiwge1xuICBzcWw6IHQuc3RyaW5nKClcbn0pO1xudmFyIFJhd1NjaGVkdWxlRGVmVjEwID0gdC5vYmplY3QoXCJSYXdTY2hlZHVsZURlZlYxMFwiLCB7XG4gIHNvdXJjZU5hbWU6IHQub3B0aW9uKHQuc3RyaW5nKCkpLFxuICB0YWJsZU5hbWU6IHQuc3RyaW5nKCksXG4gIHNjaGVkdWxlQXRDb2w6IHQudTE2KCksXG4gIGZ1bmN0aW9uTmFtZTogdC5zdHJpbmcoKVxufSk7XG52YXIgUmF3U2NoZWR1bGVEZWZWOSA9IHQub2JqZWN0KFwiUmF3U2NoZWR1bGVEZWZWOVwiLCB7XG4gIG5hbWU6IHQub3B0aW9uKHQuc3RyaW5nKCkpLFxuICByZWR1Y2VyTmFtZTogdC5zdHJpbmcoKSxcbiAgc2NoZWR1bGVkQXRDb2x1bW46IHQudTE2KClcbn0pO1xudmFyIFJhd1Njb3BlZFR5cGVOYW1lVjEwID0gdC5vYmplY3QoXCJSYXdTY29wZWRUeXBlTmFtZVYxMFwiLCB7XG4gIHNjb3BlOiB0LmFycmF5KHQuc3RyaW5nKCkpLFxuICBzb3VyY2VOYW1lOiB0LnN0cmluZygpXG59KTtcbnZhciBSYXdTY29wZWRUeXBlTmFtZVY5ID0gdC5vYmplY3QoXCJSYXdTY29wZWRUeXBlTmFtZVY5XCIsIHtcbiAgc2NvcGU6IHQuYXJyYXkodC5zdHJpbmcoKSksXG4gIG5hbWU6IHQuc3RyaW5nKClcbn0pO1xudmFyIFJhd1NlcXVlbmNlRGVmVjEwID0gdC5vYmplY3QoXCJSYXdTZXF1ZW5jZURlZlYxMFwiLCB7XG4gIHNvdXJjZU5hbWU6IHQub3B0aW9uKHQuc3RyaW5nKCkpLFxuICBjb2x1bW46IHQudTE2KCksXG4gIHN0YXJ0OiB0Lm9wdGlvbih0LmkxMjgoKSksXG4gIG1pblZhbHVlOiB0Lm9wdGlvbih0LmkxMjgoKSksXG4gIG1heFZhbHVlOiB0Lm9wdGlvbih0LmkxMjgoKSksXG4gIGluY3JlbWVudDogdC5pMTI4KClcbn0pO1xudmFyIFJhd1NlcXVlbmNlRGVmVjggPSB0Lm9iamVjdChcIlJhd1NlcXVlbmNlRGVmVjhcIiwge1xuICBzZXF1ZW5jZU5hbWU6IHQuc3RyaW5nKCksXG4gIGNvbFBvczogdC51MTYoKSxcbiAgaW5jcmVtZW50OiB0LmkxMjgoKSxcbiAgc3RhcnQ6IHQub3B0aW9uKHQuaTEyOCgpKSxcbiAgbWluVmFsdWU6IHQub3B0aW9uKHQuaTEyOCgpKSxcbiAgbWF4VmFsdWU6IHQub3B0aW9uKHQuaTEyOCgpKSxcbiAgYWxsb2NhdGVkOiB0LmkxMjgoKVxufSk7XG52YXIgUmF3U2VxdWVuY2VEZWZWOSA9IHQub2JqZWN0KFwiUmF3U2VxdWVuY2VEZWZWOVwiLCB7XG4gIG5hbWU6IHQub3B0aW9uKHQuc3RyaW5nKCkpLFxuICBjb2x1bW46IHQudTE2KCksXG4gIHN0YXJ0OiB0Lm9wdGlvbih0LmkxMjgoKSksXG4gIG1pblZhbHVlOiB0Lm9wdGlvbih0LmkxMjgoKSksXG4gIG1heFZhbHVlOiB0Lm9wdGlvbih0LmkxMjgoKSksXG4gIGluY3JlbWVudDogdC5pMTI4KClcbn0pO1xudmFyIFJhd1RhYmxlRGVmVjEwID0gdC5vYmplY3QoXCJSYXdUYWJsZURlZlYxMFwiLCB7XG4gIHNvdXJjZU5hbWU6IHQuc3RyaW5nKCksXG4gIHByb2R1Y3RUeXBlUmVmOiB0LnUzMigpLFxuICBwcmltYXJ5S2V5OiB0LmFycmF5KHQudTE2KCkpLFxuICBnZXQgaW5kZXhlcygpIHtcbiAgICByZXR1cm4gdC5hcnJheShSYXdJbmRleERlZlYxMCk7XG4gIH0sXG4gIGdldCBjb25zdHJhaW50cygpIHtcbiAgICByZXR1cm4gdC5hcnJheShSYXdDb25zdHJhaW50RGVmVjEwKTtcbiAgfSxcbiAgZ2V0IHNlcXVlbmNlcygpIHtcbiAgICByZXR1cm4gdC5hcnJheShSYXdTZXF1ZW5jZURlZlYxMCk7XG4gIH0sXG4gIGdldCB0YWJsZVR5cGUoKSB7XG4gICAgcmV0dXJuIFRhYmxlVHlwZTtcbiAgfSxcbiAgZ2V0IHRhYmxlQWNjZXNzKCkge1xuICAgIHJldHVybiBUYWJsZUFjY2VzcztcbiAgfSxcbiAgZ2V0IGRlZmF1bHRWYWx1ZXMoKSB7XG4gICAgcmV0dXJuIHQuYXJyYXkoUmF3Q29sdW1uRGVmYXVsdFZhbHVlVjEwKTtcbiAgfSxcbiAgaXNFdmVudDogdC5ib29sKClcbn0pO1xudmFyIFJhd1RhYmxlRGVmVjggPSB0Lm9iamVjdChcIlJhd1RhYmxlRGVmVjhcIiwge1xuICB0YWJsZU5hbWU6IHQuc3RyaW5nKCksXG4gIGdldCBjb2x1bW5zKCkge1xuICAgIHJldHVybiB0LmFycmF5KFJhd0NvbHVtbkRlZlY4KTtcbiAgfSxcbiAgZ2V0IGluZGV4ZXMoKSB7XG4gICAgcmV0dXJuIHQuYXJyYXkoUmF3SW5kZXhEZWZWOCk7XG4gIH0sXG4gIGdldCBjb25zdHJhaW50cygpIHtcbiAgICByZXR1cm4gdC5hcnJheShSYXdDb25zdHJhaW50RGVmVjgpO1xuICB9LFxuICBnZXQgc2VxdWVuY2VzKCkge1xuICAgIHJldHVybiB0LmFycmF5KFJhd1NlcXVlbmNlRGVmVjgpO1xuICB9LFxuICB0YWJsZVR5cGU6IHQuc3RyaW5nKCksXG4gIHRhYmxlQWNjZXNzOiB0LnN0cmluZygpLFxuICBzY2hlZHVsZWQ6IHQub3B0aW9uKHQuc3RyaW5nKCkpXG59KTtcbnZhciBSYXdUYWJsZURlZlY5ID0gdC5vYmplY3QoXCJSYXdUYWJsZURlZlY5XCIsIHtcbiAgbmFtZTogdC5zdHJpbmcoKSxcbiAgcHJvZHVjdFR5cGVSZWY6IHQudTMyKCksXG4gIHByaW1hcnlLZXk6IHQuYXJyYXkodC51MTYoKSksXG4gIGdldCBpbmRleGVzKCkge1xuICAgIHJldHVybiB0LmFycmF5KFJhd0luZGV4RGVmVjkpO1xuICB9LFxuICBnZXQgY29uc3RyYWludHMoKSB7XG4gICAgcmV0dXJuIHQuYXJyYXkoUmF3Q29uc3RyYWludERlZlY5KTtcbiAgfSxcbiAgZ2V0IHNlcXVlbmNlcygpIHtcbiAgICByZXR1cm4gdC5hcnJheShSYXdTZXF1ZW5jZURlZlY5KTtcbiAgfSxcbiAgZ2V0IHNjaGVkdWxlKCkge1xuICAgIHJldHVybiB0Lm9wdGlvbihSYXdTY2hlZHVsZURlZlY5KTtcbiAgfSxcbiAgZ2V0IHRhYmxlVHlwZSgpIHtcbiAgICByZXR1cm4gVGFibGVUeXBlO1xuICB9LFxuICBnZXQgdGFibGVBY2Nlc3MoKSB7XG4gICAgcmV0dXJuIFRhYmxlQWNjZXNzO1xuICB9XG59KTtcbnZhciBSYXdUeXBlRGVmVjEwID0gdC5vYmplY3QoXCJSYXdUeXBlRGVmVjEwXCIsIHtcbiAgZ2V0IHNvdXJjZU5hbWUoKSB7XG4gICAgcmV0dXJuIFJhd1Njb3BlZFR5cGVOYW1lVjEwO1xuICB9LFxuICB0eTogdC51MzIoKSxcbiAgY3VzdG9tT3JkZXJpbmc6IHQuYm9vbCgpXG59KTtcbnZhciBSYXdUeXBlRGVmVjkgPSB0Lm9iamVjdChcIlJhd1R5cGVEZWZWOVwiLCB7XG4gIGdldCBuYW1lKCkge1xuICAgIHJldHVybiBSYXdTY29wZWRUeXBlTmFtZVY5O1xuICB9LFxuICB0eTogdC51MzIoKSxcbiAgY3VzdG9tT3JkZXJpbmc6IHQuYm9vbCgpXG59KTtcbnZhciBSYXdVbmlxdWVDb25zdHJhaW50RGF0YVY5ID0gdC5vYmplY3QoXG4gIFwiUmF3VW5pcXVlQ29uc3RyYWludERhdGFWOVwiLFxuICB7XG4gICAgY29sdW1uczogdC5hcnJheSh0LnUxNigpKVxuICB9XG4pO1xudmFyIFJhd1ZpZXdEZWZWMTAgPSB0Lm9iamVjdChcIlJhd1ZpZXdEZWZWMTBcIiwge1xuICBzb3VyY2VOYW1lOiB0LnN0cmluZygpLFxuICBpbmRleDogdC51MzIoKSxcbiAgaXNQdWJsaWM6IHQuYm9vbCgpLFxuICBpc0Fub255bW91czogdC5ib29sKCksXG4gIGdldCBwYXJhbXMoKSB7XG4gICAgcmV0dXJuIFByb2R1Y3RUeXBlMjtcbiAgfSxcbiAgZ2V0IHJldHVyblR5cGUoKSB7XG4gICAgcmV0dXJuIEFsZ2VicmFpY1R5cGUyO1xuICB9XG59KTtcbnZhciBSYXdWaWV3RGVmVjkgPSB0Lm9iamVjdChcIlJhd1ZpZXdEZWZWOVwiLCB7XG4gIG5hbWU6IHQuc3RyaW5nKCksXG4gIGluZGV4OiB0LnUzMigpLFxuICBpc1B1YmxpYzogdC5ib29sKCksXG4gIGlzQW5vbnltb3VzOiB0LmJvb2woKSxcbiAgZ2V0IHBhcmFtcygpIHtcbiAgICByZXR1cm4gUHJvZHVjdFR5cGUyO1xuICB9LFxuICBnZXQgcmV0dXJuVHlwZSgpIHtcbiAgICByZXR1cm4gQWxnZWJyYWljVHlwZTI7XG4gIH1cbn0pO1xudmFyIFJlZHVjZXJEZWYgPSB0Lm9iamVjdChcIlJlZHVjZXJEZWZcIiwge1xuICBuYW1lOiB0LnN0cmluZygpLFxuICBnZXQgYXJncygpIHtcbiAgICByZXR1cm4gdC5hcnJheShQcm9kdWN0VHlwZUVsZW1lbnQpO1xuICB9XG59KTtcbnZhciBTdW1UeXBlMiA9IHQub2JqZWN0KFwiU3VtVHlwZVwiLCB7XG4gIGdldCB2YXJpYW50cygpIHtcbiAgICByZXR1cm4gdC5hcnJheShTdW1UeXBlVmFyaWFudCk7XG4gIH1cbn0pO1xudmFyIFN1bVR5cGVWYXJpYW50ID0gdC5vYmplY3QoXCJTdW1UeXBlVmFyaWFudFwiLCB7XG4gIG5hbWU6IHQub3B0aW9uKHQuc3RyaW5nKCkpLFxuICBnZXQgYWxnZWJyYWljVHlwZSgpIHtcbiAgICByZXR1cm4gQWxnZWJyYWljVHlwZTI7XG4gIH1cbn0pO1xudmFyIFRhYmxlQWNjZXNzID0gdC5lbnVtKFwiVGFibGVBY2Nlc3NcIiwge1xuICBQdWJsaWM6IHQudW5pdCgpLFxuICBQcml2YXRlOiB0LnVuaXQoKVxufSk7XG52YXIgVGFibGVEZXNjID0gdC5vYmplY3QoXCJUYWJsZURlc2NcIiwge1xuICBnZXQgc2NoZW1hKCkge1xuICAgIHJldHVybiBSYXdUYWJsZURlZlY4O1xuICB9LFxuICBkYXRhOiB0LnUzMigpXG59KTtcbnZhciBUYWJsZVR5cGUgPSB0LmVudW0oXCJUYWJsZVR5cGVcIiwge1xuICBTeXN0ZW06IHQudW5pdCgpLFxuICBVc2VyOiB0LnVuaXQoKVxufSk7XG52YXIgVHlwZUFsaWFzID0gdC5vYmplY3QoXCJUeXBlQWxpYXNcIiwge1xuICBuYW1lOiB0LnN0cmluZygpLFxuICB0eTogdC51MzIoKVxufSk7XG52YXIgVHlwZXNwYWNlID0gdC5vYmplY3QoXCJUeXBlc3BhY2VcIiwge1xuICBnZXQgdHlwZXMoKSB7XG4gICAgcmV0dXJuIHQuYXJyYXkoQWxnZWJyYWljVHlwZTIpO1xuICB9XG59KTtcbnZhciBWaWV3UmVzdWx0SGVhZGVyID0gdC5lbnVtKFwiVmlld1Jlc3VsdEhlYWRlclwiLCB7XG4gIFJvd0RhdGE6IHQudW5pdCgpLFxuICBSYXdTcWw6IHQuc3RyaW5nKClcbn0pO1xuXG4vLyBzcmMvbGliL3NjaGVtYS50c1xuZnVuY3Rpb24gdGFibGVUb1NjaGVtYShhY2NOYW1lLCBzY2hlbWEyLCB0YWJsZURlZikge1xuICBjb25zdCBnZXRDb2xOYW1lID0gKGkpID0+IHNjaGVtYTIucm93VHlwZS5hbGdlYnJhaWNUeXBlLnZhbHVlLmVsZW1lbnRzW2ldLm5hbWU7XG4gIGNvbnN0IHJlc29sdmVkSW5kZXhlcyA9IHRhYmxlRGVmLmluZGV4ZXMubWFwKFxuICAgIChpZHgpID0+IHtcbiAgICAgIGNvbnN0IGFjY2Vzc29yTmFtZSA9IGlkeC5hY2Nlc3Nvck5hbWU7XG4gICAgICBpZiAodHlwZW9mIGFjY2Vzc29yTmFtZSAhPT0gXCJzdHJpbmdcIiB8fCBhY2Nlc3Nvck5hbWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgYEluZGV4ICcke2lkeC5zb3VyY2VOYW1lID8/IFwiPHVua25vd24+XCJ9JyBvbiB0YWJsZSAnJHt0YWJsZURlZi5zb3VyY2VOYW1lfScgaXMgbWlzc2luZyBhY2Nlc3NvciBuYW1lYFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgY29uc3QgY29sdW1uSWRzID0gaWR4LmFsZ29yaXRobS50YWcgPT09IFwiRGlyZWN0XCIgPyBbaWR4LmFsZ29yaXRobS52YWx1ZV0gOiBpZHguYWxnb3JpdGhtLnZhbHVlO1xuICAgICAgY29uc3QgdW5pcXVlID0gdGFibGVEZWYuY29uc3RyYWludHMuc29tZShcbiAgICAgICAgKGMpID0+IGMuZGF0YS50YWcgPT09IFwiVW5pcXVlXCIgJiYgYy5kYXRhLnZhbHVlLmNvbHVtbnMuZXZlcnkoKGNvbCkgPT4gY29sdW1uSWRzLmluY2x1ZGVzKGNvbCkpXG4gICAgICApO1xuICAgICAgY29uc3QgYWxnb3JpdGhtID0ge1xuICAgICAgICBCVHJlZTogXCJidHJlZVwiLFxuICAgICAgICBIYXNoOiBcImhhc2hcIixcbiAgICAgICAgRGlyZWN0OiBcImRpcmVjdFwiXG4gICAgICB9W2lkeC5hbGdvcml0aG0udGFnXTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5hbWU6IGFjY2Vzc29yTmFtZSxcbiAgICAgICAgdW5pcXVlLFxuICAgICAgICBhbGdvcml0aG0sXG4gICAgICAgIGNvbHVtbnM6IGNvbHVtbklkcy5tYXAoZ2V0Q29sTmFtZSlcbiAgICAgIH07XG4gICAgfVxuICApO1xuICByZXR1cm4ge1xuICAgIC8vIEZvciBjbGllbnQsYHNjaGFtYS50YWJsZU5hbWVgIHdpbGwgYWx3YXlzIGJlIHRoZXJlIGFzIGNhbm9uaWNhbCBuYW1lLlxuICAgIC8vIEZvciBtb2R1bGUsIGlmIGV4cGxpY2l0IG5hbWUgaXMgbm90IHByb3ZpZGVkIHZpYSBgbmFtZWAsIGFjY2Vzc29yIG5hbWUgd2lsbFxuICAgIC8vIGJlIHVzZWQsIGl0IGlzIHN0b3JlZCBhcyBhbGlhcyBpbiBkYXRhYmFzZSwgaGVuY2Ugd29ya3MgaW4gcXVlcnkgYnVpbGRlci5cbiAgICBzb3VyY2VOYW1lOiBzY2hlbWEyLnRhYmxlTmFtZSB8fCBhY2NOYW1lLFxuICAgIGFjY2Vzc29yTmFtZTogYWNjTmFtZSxcbiAgICBjb2x1bW5zOiBzY2hlbWEyLnJvd1R5cGUucm93LFxuICAgIC8vIHR5cGVkIGFzIFRbaV1bJ3Jvd1R5cGUnXVsncm93J10gdW5kZXIgVGFibGVzVG9TY2hlbWE8VD5cbiAgICByb3dUeXBlOiBzY2hlbWEyLnJvd1NwYWNldGltZVR5cGUsXG4gICAgLy8gS2VlcCBkZWNsYXJhdGl2ZSBpbmRleGVzIGluIHRoZWlyIG9yaWdpbmFsIHNoYXBlIGZvciB0eXBlLWxldmVsIGNvbnN1bWVycy5cbiAgICBpbmRleGVzOiBzY2hlbWEyLmlkeHMsXG4gICAgY29uc3RyYWludHM6IHRhYmxlRGVmLmNvbnN0cmFpbnRzLm1hcCgoYykgPT4gKHtcbiAgICAgIG5hbWU6IGMuc291cmNlTmFtZSxcbiAgICAgIGNvbnN0cmFpbnQ6IFwidW5pcXVlXCIsXG4gICAgICBjb2x1bW5zOiBjLmRhdGEudmFsdWUuY29sdW1ucy5tYXAoZ2V0Q29sTmFtZSlcbiAgICB9KSksXG4gICAgLy8gRXhwb3NlIHJlc29sdmVkIHJ1bnRpbWUgaW5kZXhlcyBzZXBhcmF0ZWx5IHNvIHJ1bnRpbWUgdXNlcnMgZG9uJ3QgaGF2ZSB0b1xuICAgIC8vIHJlaW50ZXJwcmV0IGBpbmRleGVzYCB3aXRoIHVuc2FmZSBjYXN0cy5cbiAgICByZXNvbHZlZEluZGV4ZXMsXG4gICAgdGFibGVEZWYsXG4gICAgLi4udGFibGVEZWYuaXNFdmVudCA/IHsgaXNFdmVudDogdHJ1ZSB9IDoge31cbiAgfTtcbn1cbnZhciBNb2R1bGVDb250ZXh0ID0gY2xhc3Mge1xuICAjY29tcG91bmRUeXBlcyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7XG4gIC8qKlxuICAgKiBUaGUgZ2xvYmFsIG1vZHVsZSBkZWZpbml0aW9uIHRoYXQgZ2V0cyBwb3B1bGF0ZWQgYnkgY2FsbHMgdG8gYHJlZHVjZXIoKWAgYW5kIGxpZmVjeWNsZSBob29rcy5cbiAgICovXG4gICNtb2R1bGVEZWYgPSB7XG4gICAgdHlwZXNwYWNlOiB7IHR5cGVzOiBbXSB9LFxuICAgIHRhYmxlczogW10sXG4gICAgcmVkdWNlcnM6IFtdLFxuICAgIHR5cGVzOiBbXSxcbiAgICByb3dMZXZlbFNlY3VyaXR5OiBbXSxcbiAgICBzY2hlZHVsZXM6IFtdLFxuICAgIHByb2NlZHVyZXM6IFtdLFxuICAgIHZpZXdzOiBbXSxcbiAgICBsaWZlQ3ljbGVSZWR1Y2VyczogW10sXG4gICAgY2FzZUNvbnZlcnNpb25Qb2xpY3k6IHsgdGFnOiBcIlNuYWtlQ2FzZVwiIH0sXG4gICAgZXhwbGljaXROYW1lczoge1xuICAgICAgZW50cmllczogW11cbiAgICB9XG4gIH07XG4gIGdldCBtb2R1bGVEZWYoKSB7XG4gICAgcmV0dXJuIHRoaXMuI21vZHVsZURlZjtcbiAgfVxuICByYXdNb2R1bGVEZWZWMTAoKSB7XG4gICAgY29uc3Qgc2VjdGlvbnMgPSBbXTtcbiAgICBjb25zdCBwdXNoID0gKHMpID0+IHtcbiAgICAgIGlmIChzKSBzZWN0aW9ucy5wdXNoKHMpO1xuICAgIH07XG4gICAgY29uc3QgbW9kdWxlID0gdGhpcy4jbW9kdWxlRGVmO1xuICAgIHB1c2gobW9kdWxlLnR5cGVzcGFjZSAmJiB7IHRhZzogXCJUeXBlc3BhY2VcIiwgdmFsdWU6IG1vZHVsZS50eXBlc3BhY2UgfSk7XG4gICAgcHVzaChtb2R1bGUudHlwZXMgJiYgeyB0YWc6IFwiVHlwZXNcIiwgdmFsdWU6IG1vZHVsZS50eXBlcyB9KTtcbiAgICBwdXNoKG1vZHVsZS50YWJsZXMgJiYgeyB0YWc6IFwiVGFibGVzXCIsIHZhbHVlOiBtb2R1bGUudGFibGVzIH0pO1xuICAgIHB1c2gobW9kdWxlLnJlZHVjZXJzICYmIHsgdGFnOiBcIlJlZHVjZXJzXCIsIHZhbHVlOiBtb2R1bGUucmVkdWNlcnMgfSk7XG4gICAgcHVzaChtb2R1bGUucHJvY2VkdXJlcyAmJiB7IHRhZzogXCJQcm9jZWR1cmVzXCIsIHZhbHVlOiBtb2R1bGUucHJvY2VkdXJlcyB9KTtcbiAgICBwdXNoKG1vZHVsZS52aWV3cyAmJiB7IHRhZzogXCJWaWV3c1wiLCB2YWx1ZTogbW9kdWxlLnZpZXdzIH0pO1xuICAgIHB1c2gobW9kdWxlLnNjaGVkdWxlcyAmJiB7IHRhZzogXCJTY2hlZHVsZXNcIiwgdmFsdWU6IG1vZHVsZS5zY2hlZHVsZXMgfSk7XG4gICAgcHVzaChcbiAgICAgIG1vZHVsZS5saWZlQ3ljbGVSZWR1Y2VycyAmJiB7XG4gICAgICAgIHRhZzogXCJMaWZlQ3ljbGVSZWR1Y2Vyc1wiLFxuICAgICAgICB2YWx1ZTogbW9kdWxlLmxpZmVDeWNsZVJlZHVjZXJzXG4gICAgICB9XG4gICAgKTtcbiAgICBwdXNoKFxuICAgICAgbW9kdWxlLnJvd0xldmVsU2VjdXJpdHkgJiYge1xuICAgICAgICB0YWc6IFwiUm93TGV2ZWxTZWN1cml0eVwiLFxuICAgICAgICB2YWx1ZTogbW9kdWxlLnJvd0xldmVsU2VjdXJpdHlcbiAgICAgIH1cbiAgICApO1xuICAgIHB1c2goXG4gICAgICBtb2R1bGUuZXhwbGljaXROYW1lcyAmJiB7XG4gICAgICAgIHRhZzogXCJFeHBsaWNpdE5hbWVzXCIsXG4gICAgICAgIHZhbHVlOiBtb2R1bGUuZXhwbGljaXROYW1lc1xuICAgICAgfVxuICAgICk7XG4gICAgcHVzaChcbiAgICAgIG1vZHVsZS5jYXNlQ29udmVyc2lvblBvbGljeSAmJiB7XG4gICAgICAgIHRhZzogXCJDYXNlQ29udmVyc2lvblBvbGljeVwiLFxuICAgICAgICB2YWx1ZTogbW9kdWxlLmNhc2VDb252ZXJzaW9uUG9saWN5XG4gICAgICB9XG4gICAgKTtcbiAgICByZXR1cm4geyBzZWN0aW9ucyB9O1xuICB9XG4gIC8qKlxuICAgKiBTZXQgdGhlIGNhc2UgY29udmVyc2lvbiBwb2xpY3kgZm9yIHRoaXMgbW9kdWxlLlxuICAgKiBDYWxsZWQgYnkgdGhlIHNldHRpbmdzIG1lY2hhbmlzbS5cbiAgICovXG4gIHNldENhc2VDb252ZXJzaW9uUG9saWN5KHBvbGljeSkge1xuICAgIHRoaXMuI21vZHVsZURlZi5jYXNlQ29udmVyc2lvblBvbGljeSA9IHBvbGljeTtcbiAgfVxuICBnZXQgdHlwZXNwYWNlKCkge1xuICAgIHJldHVybiB0aGlzLiNtb2R1bGVEZWYudHlwZXNwYWNlO1xuICB9XG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgYWN0dWFsIHR5cGUgb2YgYSBUeXBlQnVpbGRlciBieSBmb2xsb3dpbmcgaXRzIHJlZmVyZW5jZXMgdW50aWwgaXQgcmVhY2hlcyBhIG5vbi1yZWYgdHlwZS5cbiAgICogQHBhcmFtIHR5cGVzcGFjZSBUaGUgdHlwZXNwYWNlIHRvIHJlc29sdmUgdHlwZXMgYWdhaW5zdC5cbiAgICogQHBhcmFtIHR5cGVCdWlsZGVyIFRoZSBUeXBlQnVpbGRlciB0byByZXNvbHZlLlxuICAgKiBAcmV0dXJucyBUaGUgcmVzb2x2ZWQgYWxnZWJyYWljIHR5cGUuXG4gICAqL1xuICByZXNvbHZlVHlwZSh0eXBlQnVpbGRlcikge1xuICAgIGxldCB0eSA9IHR5cGVCdWlsZGVyLmFsZ2VicmFpY1R5cGU7XG4gICAgd2hpbGUgKHR5LnRhZyA9PT0gXCJSZWZcIikge1xuICAgICAgdHkgPSB0aGlzLnR5cGVzcGFjZS50eXBlc1t0eS52YWx1ZV07XG4gICAgfVxuICAgIHJldHVybiB0eTtcbiAgfVxuICAvKipcbiAgICogQWRkcyBhIHR5cGUgdG8gdGhlIG1vZHVsZSBkZWZpbml0aW9uJ3MgdHlwZXNwYWNlIGFzIGEgYFJlZmAgaWYgaXQgaXMgYSBuYW1lZCBjb21wb3VuZCB0eXBlIChQcm9kdWN0IG9yIFN1bSkuXG4gICAqIE90aGVyd2lzZSwgcmV0dXJucyB0aGUgdHlwZSBhcyBpcy5cbiAgICogQHBhcmFtIG5hbWVcbiAgICogQHBhcmFtIHR5XG4gICAqIEByZXR1cm5zXG4gICAqL1xuICByZWdpc3RlclR5cGVzUmVjdXJzaXZlbHkodHlwZUJ1aWxkZXIpIHtcbiAgICBpZiAodHlwZUJ1aWxkZXIgaW5zdGFuY2VvZiBQcm9kdWN0QnVpbGRlciAmJiAhaXNVbml0KHR5cGVCdWlsZGVyKSB8fCB0eXBlQnVpbGRlciBpbnN0YW5jZW9mIFN1bUJ1aWxkZXIgfHwgdHlwZUJ1aWxkZXIgaW5zdGFuY2VvZiBSb3dCdWlsZGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy4jcmVnaXN0ZXJDb21wb3VuZFR5cGVSZWN1cnNpdmVseSh0eXBlQnVpbGRlcik7XG4gICAgfSBlbHNlIGlmICh0eXBlQnVpbGRlciBpbnN0YW5jZW9mIE9wdGlvbkJ1aWxkZXIpIHtcbiAgICAgIHJldHVybiBuZXcgT3B0aW9uQnVpbGRlcihcbiAgICAgICAgdGhpcy5yZWdpc3RlclR5cGVzUmVjdXJzaXZlbHkodHlwZUJ1aWxkZXIudmFsdWUpXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAodHlwZUJ1aWxkZXIgaW5zdGFuY2VvZiBSZXN1bHRCdWlsZGVyKSB7XG4gICAgICByZXR1cm4gbmV3IFJlc3VsdEJ1aWxkZXIoXG4gICAgICAgIHRoaXMucmVnaXN0ZXJUeXBlc1JlY3Vyc2l2ZWx5KHR5cGVCdWlsZGVyLm9rKSxcbiAgICAgICAgdGhpcy5yZWdpc3RlclR5cGVzUmVjdXJzaXZlbHkodHlwZUJ1aWxkZXIuZXJyKVxuICAgICAgKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVCdWlsZGVyIGluc3RhbmNlb2YgQXJyYXlCdWlsZGVyKSB7XG4gICAgICByZXR1cm4gbmV3IEFycmF5QnVpbGRlcihcbiAgICAgICAgdGhpcy5yZWdpc3RlclR5cGVzUmVjdXJzaXZlbHkodHlwZUJ1aWxkZXIuZWxlbWVudClcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0eXBlQnVpbGRlcjtcbiAgICB9XG4gIH1cbiAgI3JlZ2lzdGVyQ29tcG91bmRUeXBlUmVjdXJzaXZlbHkodHlwZUJ1aWxkZXIpIHtcbiAgICBjb25zdCB0eSA9IHR5cGVCdWlsZGVyLmFsZ2VicmFpY1R5cGU7XG4gICAgY29uc3QgbmFtZSA9IHR5cGVCdWlsZGVyLnR5cGVOYW1lO1xuICAgIGlmIChuYW1lID09PSB2b2lkIDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYE1pc3NpbmcgdHlwZSBuYW1lIGZvciAke3R5cGVCdWlsZGVyLmNvbnN0cnVjdG9yLm5hbWUgPz8gXCJUeXBlQnVpbGRlclwifSAke0pTT04uc3RyaW5naWZ5KHR5cGVCdWlsZGVyKX1gXG4gICAgICApO1xuICAgIH1cbiAgICBsZXQgciA9IHRoaXMuI2NvbXBvdW5kVHlwZXMuZ2V0KHR5KTtcbiAgICBpZiAociAhPSBudWxsKSB7XG4gICAgICByZXR1cm4gcjtcbiAgICB9XG4gICAgY29uc3QgbmV3VHkgPSB0eXBlQnVpbGRlciBpbnN0YW5jZW9mIFJvd0J1aWxkZXIgfHwgdHlwZUJ1aWxkZXIgaW5zdGFuY2VvZiBQcm9kdWN0QnVpbGRlciA/IHtcbiAgICAgIHRhZzogXCJQcm9kdWN0XCIsXG4gICAgICB2YWx1ZTogeyBlbGVtZW50czogW10gfVxuICAgIH0gOiB7XG4gICAgICB0YWc6IFwiU3VtXCIsXG4gICAgICB2YWx1ZTogeyB2YXJpYW50czogW10gfVxuICAgIH07XG4gICAgciA9IG5ldyBSZWZCdWlsZGVyKHRoaXMuI21vZHVsZURlZi50eXBlc3BhY2UudHlwZXMubGVuZ3RoKTtcbiAgICB0aGlzLiNtb2R1bGVEZWYudHlwZXNwYWNlLnR5cGVzLnB1c2gobmV3VHkpO1xuICAgIHRoaXMuI2NvbXBvdW5kVHlwZXMuc2V0KHR5LCByKTtcbiAgICBpZiAodHlwZUJ1aWxkZXIgaW5zdGFuY2VvZiBSb3dCdWlsZGVyKSB7XG4gICAgICBmb3IgKGNvbnN0IFtuYW1lMiwgZWxlbV0gb2YgT2JqZWN0LmVudHJpZXModHlwZUJ1aWxkZXIucm93KSkge1xuICAgICAgICBuZXdUeS52YWx1ZS5lbGVtZW50cy5wdXNoKHtcbiAgICAgICAgICBuYW1lOiBuYW1lMixcbiAgICAgICAgICBhbGdlYnJhaWNUeXBlOiB0aGlzLnJlZ2lzdGVyVHlwZXNSZWN1cnNpdmVseShlbGVtLnR5cGVCdWlsZGVyKS5hbGdlYnJhaWNUeXBlXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZUJ1aWxkZXIgaW5zdGFuY2VvZiBQcm9kdWN0QnVpbGRlcikge1xuICAgICAgZm9yIChjb25zdCBbbmFtZTIsIGVsZW1dIG9mIE9iamVjdC5lbnRyaWVzKHR5cGVCdWlsZGVyLmVsZW1lbnRzKSkge1xuICAgICAgICBuZXdUeS52YWx1ZS5lbGVtZW50cy5wdXNoKHtcbiAgICAgICAgICBuYW1lOiBuYW1lMixcbiAgICAgICAgICBhbGdlYnJhaWNUeXBlOiB0aGlzLnJlZ2lzdGVyVHlwZXNSZWN1cnNpdmVseShlbGVtKS5hbGdlYnJhaWNUeXBlXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodHlwZUJ1aWxkZXIgaW5zdGFuY2VvZiBTdW1CdWlsZGVyKSB7XG4gICAgICBmb3IgKGNvbnN0IFtuYW1lMiwgdmFyaWFudF0gb2YgT2JqZWN0LmVudHJpZXModHlwZUJ1aWxkZXIudmFyaWFudHMpKSB7XG4gICAgICAgIG5ld1R5LnZhbHVlLnZhcmlhbnRzLnB1c2goe1xuICAgICAgICAgIG5hbWU6IG5hbWUyLFxuICAgICAgICAgIGFsZ2VicmFpY1R5cGU6IHRoaXMucmVnaXN0ZXJUeXBlc1JlY3Vyc2l2ZWx5KHZhcmlhbnQpLmFsZ2VicmFpY1R5cGVcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuI21vZHVsZURlZi50eXBlcy5wdXNoKHtcbiAgICAgIHNvdXJjZU5hbWU6IHNwbGl0TmFtZShuYW1lKSxcbiAgICAgIHR5OiByLnJlZixcbiAgICAgIGN1c3RvbU9yZGVyaW5nOiB0cnVlXG4gICAgfSk7XG4gICAgcmV0dXJuIHI7XG4gIH1cbn07XG5mdW5jdGlvbiBpc1VuaXQodHlwZUJ1aWxkZXIpIHtcbiAgcmV0dXJuIHR5cGVCdWlsZGVyLnR5cGVOYW1lID09IG51bGwgJiYgdHlwZUJ1aWxkZXIuYWxnZWJyYWljVHlwZS52YWx1ZS5lbGVtZW50cy5sZW5ndGggPT09IDA7XG59XG5mdW5jdGlvbiBzcGxpdE5hbWUobmFtZSkge1xuICBjb25zdCBzY29wZSA9IG5hbWUuc3BsaXQoXCIuXCIpO1xuICByZXR1cm4geyBzb3VyY2VOYW1lOiBzY29wZS5wb3AoKSwgc2NvcGUgfTtcbn1cblxuLy8gc3JjL3NlcnZlci9odHRwX2ludGVybmFsLnRzXG52YXIgaW1wb3J0X3N0YXR1c2VzID0gX190b0VTTShyZXF1aXJlX3N0YXR1c2VzKCkpO1xuXG4vLyBzcmMvc2VydmVyL3JhbmdlLnRzXG52YXIgUmFuZ2UgPSBjbGFzcyB7XG4gICNmcm9tO1xuICAjdG87XG4gIGNvbnN0cnVjdG9yKGZyb20sIHRvKSB7XG4gICAgdGhpcy4jZnJvbSA9IGZyb20gPz8geyB0YWc6IFwidW5ib3VuZGVkXCIgfTtcbiAgICB0aGlzLiN0byA9IHRvID8/IHsgdGFnOiBcInVuYm91bmRlZFwiIH07XG4gIH1cbiAgZ2V0IGZyb20oKSB7XG4gICAgcmV0dXJuIHRoaXMuI2Zyb207XG4gIH1cbiAgZ2V0IHRvKCkge1xuICAgIHJldHVybiB0aGlzLiN0bztcbiAgfVxufTtcblxuLy8gc3JjL2xpYi90YWJsZS50c1xuZnVuY3Rpb24gdGFibGUob3B0cywgcm93LCAuLi5fKSB7XG4gIGNvbnN0IHtcbiAgICBuYW1lLFxuICAgIHB1YmxpYzogaXNQdWJsaWMgPSBmYWxzZSxcbiAgICBpbmRleGVzOiB1c2VySW5kZXhlcyA9IFtdLFxuICAgIHNjaGVkdWxlZCxcbiAgICBldmVudDogaXNFdmVudCA9IGZhbHNlXG4gIH0gPSBvcHRzO1xuICBjb25zdCBjb2xJZHMgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpO1xuICBjb25zdCBjb2xOYW1lTGlzdCA9IFtdO1xuICBpZiAoIShyb3cgaW5zdGFuY2VvZiBSb3dCdWlsZGVyKSkge1xuICAgIHJvdyA9IG5ldyBSb3dCdWlsZGVyKHJvdyk7XG4gIH1cbiAgcm93LmFsZ2VicmFpY1R5cGUudmFsdWUuZWxlbWVudHMuZm9yRWFjaCgoZWxlbSwgaSkgPT4ge1xuICAgIGNvbElkcy5zZXQoZWxlbS5uYW1lLCBpKTtcbiAgICBjb2xOYW1lTGlzdC5wdXNoKGVsZW0ubmFtZSk7XG4gIH0pO1xuICBjb25zdCBwayA9IFtdO1xuICBjb25zdCBpbmRleGVzID0gW107XG4gIGNvbnN0IGNvbnN0cmFpbnRzID0gW107XG4gIGNvbnN0IHNlcXVlbmNlcyA9IFtdO1xuICBsZXQgc2NoZWR1bGVBdENvbDtcbiAgY29uc3QgZGVmYXVsdFZhbHVlcyA9IFtdO1xuICBmb3IgKGNvbnN0IFtuYW1lMiwgYnVpbGRlcl0gb2YgT2JqZWN0LmVudHJpZXMocm93LnJvdykpIHtcbiAgICBjb25zdCBtZXRhID0gYnVpbGRlci5jb2x1bW5NZXRhZGF0YTtcbiAgICBpZiAobWV0YS5pc1ByaW1hcnlLZXkpIHtcbiAgICAgIHBrLnB1c2goY29sSWRzLmdldChuYW1lMikpO1xuICAgIH1cbiAgICBjb25zdCBpc1VuaXF1ZSA9IG1ldGEuaXNVbmlxdWUgfHwgbWV0YS5pc1ByaW1hcnlLZXk7XG4gICAgaWYgKG1ldGEuaW5kZXhUeXBlIHx8IGlzVW5pcXVlKSB7XG4gICAgICBjb25zdCBhbGdvID0gbWV0YS5pbmRleFR5cGUgPz8gXCJidHJlZVwiO1xuICAgICAgY29uc3QgaWQgPSBjb2xJZHMuZ2V0KG5hbWUyKTtcbiAgICAgIGxldCBhbGdvcml0aG07XG4gICAgICBzd2l0Y2ggKGFsZ28pIHtcbiAgICAgICAgY2FzZSBcImJ0cmVlXCI6XG4gICAgICAgICAgYWxnb3JpdGhtID0gUmF3SW5kZXhBbGdvcml0aG0uQlRyZWUoW2lkXSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJoYXNoXCI6XG4gICAgICAgICAgYWxnb3JpdGhtID0gUmF3SW5kZXhBbGdvcml0aG0uSGFzaChbaWRdKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcImRpcmVjdFwiOlxuICAgICAgICAgIGFsZ29yaXRobSA9IFJhd0luZGV4QWxnb3JpdGhtLkRpcmVjdChpZCk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpbmRleGVzLnB1c2goe1xuICAgICAgICBzb3VyY2VOYW1lOiB2b2lkIDAsXG4gICAgICAgIC8vIFVubmFtZWQgaW5kZXhlcyB3aWxsIGJlIGFzc2lnbmVkIGEgZ2xvYmFsbHkgdW5pcXVlIG5hbWVcbiAgICAgICAgYWNjZXNzb3JOYW1lOiBuYW1lMixcbiAgICAgICAgYWxnb3JpdGhtXG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKGlzVW5pcXVlKSB7XG4gICAgICBjb25zdHJhaW50cy5wdXNoKHtcbiAgICAgICAgc291cmNlTmFtZTogdm9pZCAwLFxuICAgICAgICBkYXRhOiB7IHRhZzogXCJVbmlxdWVcIiwgdmFsdWU6IHsgY29sdW1uczogW2NvbElkcy5nZXQobmFtZTIpXSB9IH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAobWV0YS5pc0F1dG9JbmNyZW1lbnQpIHtcbiAgICAgIHNlcXVlbmNlcy5wdXNoKHtcbiAgICAgICAgc291cmNlTmFtZTogdm9pZCAwLFxuICAgICAgICBzdGFydDogdm9pZCAwLFxuICAgICAgICBtaW5WYWx1ZTogdm9pZCAwLFxuICAgICAgICBtYXhWYWx1ZTogdm9pZCAwLFxuICAgICAgICBjb2x1bW46IGNvbElkcy5nZXQobmFtZTIpLFxuICAgICAgICBpbmNyZW1lbnQ6IDFuXG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKG1ldGEuZGVmYXVsdFZhbHVlKSB7XG4gICAgICBjb25zdCB3cml0ZXIgPSBuZXcgQmluYXJ5V3JpdGVyKDE2KTtcbiAgICAgIGJ1aWxkZXIuc2VyaWFsaXplKHdyaXRlciwgbWV0YS5kZWZhdWx0VmFsdWUpO1xuICAgICAgZGVmYXVsdFZhbHVlcy5wdXNoKHtcbiAgICAgICAgY29sSWQ6IGNvbElkcy5nZXQobmFtZTIpLFxuICAgICAgICB2YWx1ZTogd3JpdGVyLmdldEJ1ZmZlcigpXG4gICAgICB9KTtcbiAgICB9XG4gICAgaWYgKHNjaGVkdWxlZCkge1xuICAgICAgY29uc3QgYWxnZWJyYWljVHlwZSA9IGJ1aWxkZXIudHlwZUJ1aWxkZXIuYWxnZWJyYWljVHlwZTtcbiAgICAgIGlmIChzY2hlZHVsZV9hdF9kZWZhdWx0LmlzU2NoZWR1bGVBdChhbGdlYnJhaWNUeXBlKSkge1xuICAgICAgICBzY2hlZHVsZUF0Q29sID0gY29sSWRzLmdldChuYW1lMik7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGZvciAoY29uc3QgaW5kZXhPcHRzIG9mIHVzZXJJbmRleGVzID8/IFtdKSB7XG4gICAgY29uc3QgYWNjZXNzb3IgPSBpbmRleE9wdHMuYWNjZXNzb3I7XG4gICAgaWYgKHR5cGVvZiBhY2Nlc3NvciAhPT0gXCJzdHJpbmdcIiB8fCBhY2Nlc3Nvci5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnN0IHRhYmxlTGFiZWwgPSBuYW1lID8/IFwiPHVubmFtZWQ+XCI7XG4gICAgICBjb25zdCBpbmRleExhYmVsID0gaW5kZXhPcHRzLm5hbWUgPz8gXCI8dW5uYW1lZD5cIjtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgIGBJbmRleCAnJHtpbmRleExhYmVsfScgb24gdGFibGUgJyR7dGFibGVMYWJlbH0nIG11c3QgZGVmaW5lIGEgbm9uLWVtcHR5ICdhY2Nlc3NvcidgXG4gICAgICApO1xuICAgIH1cbiAgICBsZXQgYWxnb3JpdGhtO1xuICAgIHN3aXRjaCAoaW5kZXhPcHRzLmFsZ29yaXRobSkge1xuICAgICAgY2FzZSBcImJ0cmVlXCI6XG4gICAgICAgIGFsZ29yaXRobSA9IHtcbiAgICAgICAgICB0YWc6IFwiQlRyZWVcIixcbiAgICAgICAgICB2YWx1ZTogaW5kZXhPcHRzLmNvbHVtbnMubWFwKChjKSA9PiBjb2xJZHMuZ2V0KGMpKVxuICAgICAgICB9O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJoYXNoXCI6XG4gICAgICAgIGFsZ29yaXRobSA9IHtcbiAgICAgICAgICB0YWc6IFwiSGFzaFwiLFxuICAgICAgICAgIHZhbHVlOiBpbmRleE9wdHMuY29sdW1ucy5tYXAoKGMpID0+IGNvbElkcy5nZXQoYykpXG4gICAgICAgIH07XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcImRpcmVjdFwiOlxuICAgICAgICBhbGdvcml0aG0gPSB7IHRhZzogXCJEaXJlY3RcIiwgdmFsdWU6IGNvbElkcy5nZXQoaW5kZXhPcHRzLmNvbHVtbikgfTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIGluZGV4ZXMucHVzaCh7XG4gICAgICBzb3VyY2VOYW1lOiB2b2lkIDAsXG4gICAgICBhY2Nlc3Nvck5hbWU6IGFjY2Vzc29yLFxuICAgICAgYWxnb3JpdGhtLFxuICAgICAgY2Fub25pY2FsTmFtZTogaW5kZXhPcHRzLm5hbWVcbiAgICB9KTtcbiAgfVxuICBmb3IgKGNvbnN0IGNvbnN0cmFpbnRPcHRzIG9mIG9wdHMuY29uc3RyYWludHMgPz8gW10pIHtcbiAgICBpZiAoY29uc3RyYWludE9wdHMuY29uc3RyYWludCA9PT0gXCJ1bmlxdWVcIikge1xuICAgICAgY29uc3QgZGF0YSA9IHtcbiAgICAgICAgdGFnOiBcIlVuaXF1ZVwiLFxuICAgICAgICB2YWx1ZTogeyBjb2x1bW5zOiBjb25zdHJhaW50T3B0cy5jb2x1bW5zLm1hcCgoYykgPT4gY29sSWRzLmdldChjKSkgfVxuICAgICAgfTtcbiAgICAgIGNvbnN0cmFpbnRzLnB1c2goeyBzb3VyY2VOYW1lOiBjb25zdHJhaW50T3B0cy5uYW1lLCBkYXRhIH0pO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICB9XG4gIGNvbnN0IHByb2R1Y3RUeXBlID0gcm93LmFsZ2VicmFpY1R5cGUudmFsdWU7XG4gIGNvbnN0IHNjaGVkdWxlID0gc2NoZWR1bGVkICYmIHNjaGVkdWxlQXRDb2wgIT09IHZvaWQgMCA/IHsgc2NoZWR1bGVBdENvbCwgcmVkdWNlcjogc2NoZWR1bGVkIH0gOiB2b2lkIDA7XG4gIHJldHVybiB7XG4gICAgcm93VHlwZTogcm93LFxuICAgIHRhYmxlTmFtZTogbmFtZSxcbiAgICByb3dTcGFjZXRpbWVUeXBlOiBwcm9kdWN0VHlwZSxcbiAgICB0YWJsZURlZjogKGN0eCwgYWNjTmFtZSkgPT4ge1xuICAgICAgY29uc3QgdGFibGVOYW1lID0gbmFtZSA/PyBhY2NOYW1lO1xuICAgICAgaWYgKHJvdy50eXBlTmFtZSA9PT0gdm9pZCAwKSB7XG4gICAgICAgIHJvdy50eXBlTmFtZSA9IHRvUGFzY2FsQ2FzZSh0YWJsZU5hbWUpO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBpbmRleCBvZiBpbmRleGVzKSB7XG4gICAgICAgIGNvbnN0IGNvbHMgPSBpbmRleC5hbGdvcml0aG0udGFnID09PSBcIkRpcmVjdFwiID8gW2luZGV4LmFsZ29yaXRobS52YWx1ZV0gOiBpbmRleC5hbGdvcml0aG0udmFsdWU7XG4gICAgICAgIGNvbnN0IGNvbFMgPSBjb2xzLm1hcCgoaSkgPT4gY29sTmFtZUxpc3RbaV0pLmpvaW4oXCJfXCIpO1xuICAgICAgICBjb25zdCBzb3VyY2VOYW1lID0gaW5kZXguc291cmNlTmFtZSA9IGAke2FjY05hbWV9XyR7Y29sU31faWR4XyR7aW5kZXguYWxnb3JpdGhtLnRhZy50b0xvd2VyQ2FzZSgpfWA7XG4gICAgICAgIGNvbnN0IHsgY2Fub25pY2FsTmFtZSB9ID0gaW5kZXg7XG4gICAgICAgIGlmIChjYW5vbmljYWxOYW1lICE9PSB2b2lkIDApIHtcbiAgICAgICAgICBjdHgubW9kdWxlRGVmLmV4cGxpY2l0TmFtZXMuZW50cmllcy5wdXNoKFxuICAgICAgICAgICAgRXhwbGljaXROYW1lRW50cnkuSW5kZXgoeyBzb3VyY2VOYW1lLCBjYW5vbmljYWxOYW1lIH0pXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc291cmNlTmFtZTogYWNjTmFtZSxcbiAgICAgICAgcHJvZHVjdFR5cGVSZWY6IGN0eC5yZWdpc3RlclR5cGVzUmVjdXJzaXZlbHkocm93KS5yZWYsXG4gICAgICAgIHByaW1hcnlLZXk6IHBrLFxuICAgICAgICBpbmRleGVzLFxuICAgICAgICBjb25zdHJhaW50cyxcbiAgICAgICAgc2VxdWVuY2VzLFxuICAgICAgICB0YWJsZVR5cGU6IHsgdGFnOiBcIlVzZXJcIiB9LFxuICAgICAgICB0YWJsZUFjY2VzczogeyB0YWc6IGlzUHVibGljID8gXCJQdWJsaWNcIiA6IFwiUHJpdmF0ZVwiIH0sXG4gICAgICAgIGRlZmF1bHRWYWx1ZXMsXG4gICAgICAgIGlzRXZlbnRcbiAgICAgIH07XG4gICAgfSxcbiAgICAvLyBQcmVzZXJ2ZSB0aGUgZGVjbGFyZWQgaW5kZXggb3B0aW9ucyBhcyBydW50aW1lIGRhdGEgc28gYHRhYmxlVG9TY2hlbWFgXG4gICAgLy8gY2FuIGV4cG9zZSB0aGVtIHdpdGhvdXQgdHlwZS1zbXVnZ2xpbmcuXG4gICAgaWR4czogdXNlckluZGV4ZXMsXG4gICAgY29uc3RyYWludHMsXG4gICAgc2NoZWR1bGVcbiAgfTtcbn1cblxuLy8gc3JjL2xpYi9xdWVyeS50c1xudmFyIFF1ZXJ5QnJhbmQgPSBTeW1ib2woXCJRdWVyeUJyYW5kXCIpO1xudmFyIGlzUm93VHlwZWRRdWVyeSA9ICh2YWwpID0+ICEhdmFsICYmIHR5cGVvZiB2YWwgPT09IFwib2JqZWN0XCIgJiYgUXVlcnlCcmFuZCBpbiB2YWw7XG52YXIgaXNUeXBlZFF1ZXJ5ID0gKHZhbCkgPT4gISF2YWwgJiYgdHlwZW9mIHZhbCA9PT0gXCJvYmplY3RcIiAmJiBRdWVyeUJyYW5kIGluIHZhbDtcbmZ1bmN0aW9uIHRvU3FsKHEpIHtcbiAgcmV0dXJuIHEudG9TcWwoKTtcbn1cbnZhciBTZW1pam9pbkltcGwgPSBjbGFzcyBfU2VtaWpvaW5JbXBsIHtcbiAgY29uc3RydWN0b3Ioc291cmNlUXVlcnksIGZpbHRlclF1ZXJ5LCBqb2luQ29uZGl0aW9uKSB7XG4gICAgdGhpcy5zb3VyY2VRdWVyeSA9IHNvdXJjZVF1ZXJ5O1xuICAgIHRoaXMuZmlsdGVyUXVlcnkgPSBmaWx0ZXJRdWVyeTtcbiAgICB0aGlzLmpvaW5Db25kaXRpb24gPSBqb2luQ29uZGl0aW9uO1xuICAgIGlmIChzb3VyY2VRdWVyeS50YWJsZS5zb3VyY2VOYW1lID09PSBmaWx0ZXJRdWVyeS50YWJsZS5zb3VyY2VOYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3Qgc2VtaWpvaW4gYSB0YWJsZSB0byBpdHNlbGZcIik7XG4gICAgfVxuICB9XG4gIFtRdWVyeUJyYW5kXSA9IHRydWU7XG4gIHR5cGUgPSBcInNlbWlqb2luXCI7XG4gIGJ1aWxkKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIHdoZXJlKHByZWRpY2F0ZSkge1xuICAgIGNvbnN0IG5leHRTb3VyY2VRdWVyeSA9IHRoaXMuc291cmNlUXVlcnkud2hlcmUocHJlZGljYXRlKTtcbiAgICByZXR1cm4gbmV3IF9TZW1pam9pbkltcGwoXG4gICAgICBuZXh0U291cmNlUXVlcnksXG4gICAgICB0aGlzLmZpbHRlclF1ZXJ5LFxuICAgICAgdGhpcy5qb2luQ29uZGl0aW9uXG4gICAgKTtcbiAgfVxuICB0b1NxbCgpIHtcbiAgICBjb25zdCBsZWZ0ID0gdGhpcy5maWx0ZXJRdWVyeTtcbiAgICBjb25zdCByaWdodCA9IHRoaXMuc291cmNlUXVlcnk7XG4gICAgY29uc3QgbGVmdFRhYmxlID0gcXVvdGVJZGVudGlmaWVyKGxlZnQudGFibGUuc291cmNlTmFtZSk7XG4gICAgY29uc3QgcmlnaHRUYWJsZSA9IHF1b3RlSWRlbnRpZmllcihyaWdodC50YWJsZS5zb3VyY2VOYW1lKTtcbiAgICBsZXQgc3FsID0gYFNFTEVDVCAke3JpZ2h0VGFibGV9LiogRlJPTSAke2xlZnRUYWJsZX0gSk9JTiAke3JpZ2h0VGFibGV9IE9OICR7Ym9vbGVhbkV4cHJUb1NxbCh0aGlzLmpvaW5Db25kaXRpb24pfWA7XG4gICAgY29uc3QgY2xhdXNlcyA9IFtdO1xuICAgIGlmIChsZWZ0LndoZXJlQ2xhdXNlKSB7XG4gICAgICBjbGF1c2VzLnB1c2goYm9vbGVhbkV4cHJUb1NxbChsZWZ0LndoZXJlQ2xhdXNlKSk7XG4gICAgfVxuICAgIGlmIChyaWdodC53aGVyZUNsYXVzZSkge1xuICAgICAgY2xhdXNlcy5wdXNoKGJvb2xlYW5FeHByVG9TcWwocmlnaHQud2hlcmVDbGF1c2UpKTtcbiAgICB9XG4gICAgaWYgKGNsYXVzZXMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3Qgd2hlcmVTcWwgPSBjbGF1c2VzLmxlbmd0aCA9PT0gMSA/IGNsYXVzZXNbMF0gOiBjbGF1c2VzLm1hcCh3cmFwSW5QYXJlbnMpLmpvaW4oXCIgQU5EIFwiKTtcbiAgICAgIHNxbCArPSBgIFdIRVJFICR7d2hlcmVTcWx9YDtcbiAgICB9XG4gICAgcmV0dXJuIHNxbDtcbiAgfVxufTtcbnZhciBGcm9tQnVpbGRlciA9IGNsYXNzIF9Gcm9tQnVpbGRlciB7XG4gIGNvbnN0cnVjdG9yKHRhYmxlMiwgd2hlcmVDbGF1c2UpIHtcbiAgICB0aGlzLnRhYmxlID0gdGFibGUyO1xuICAgIHRoaXMud2hlcmVDbGF1c2UgPSB3aGVyZUNsYXVzZTtcbiAgfVxuICBbUXVlcnlCcmFuZF0gPSB0cnVlO1xuICB3aGVyZShwcmVkaWNhdGUpIHtcbiAgICBjb25zdCBuZXdDb25kaXRpb24gPSBub3JtYWxpemVQcmVkaWNhdGVFeHByKHByZWRpY2F0ZSh0aGlzLnRhYmxlLmNvbHMpKTtcbiAgICBjb25zdCBuZXh0V2hlcmUgPSB0aGlzLndoZXJlQ2xhdXNlID8gdGhpcy53aGVyZUNsYXVzZS5hbmQobmV3Q29uZGl0aW9uKSA6IG5ld0NvbmRpdGlvbjtcbiAgICByZXR1cm4gbmV3IF9Gcm9tQnVpbGRlcih0aGlzLnRhYmxlLCBuZXh0V2hlcmUpO1xuICB9XG4gIHJpZ2h0U2VtaWpvaW4ocmlnaHQsIG9uKSB7XG4gICAgY29uc3Qgc291cmNlUXVlcnkgPSBuZXcgX0Zyb21CdWlsZGVyKHJpZ2h0KTtcbiAgICBjb25zdCBqb2luQ29uZGl0aW9uID0gb24oXG4gICAgICB0aGlzLnRhYmxlLmluZGV4ZWRDb2xzLFxuICAgICAgcmlnaHQuaW5kZXhlZENvbHNcbiAgICApO1xuICAgIHJldHVybiBuZXcgU2VtaWpvaW5JbXBsKHNvdXJjZVF1ZXJ5LCB0aGlzLCBqb2luQ29uZGl0aW9uKTtcbiAgfVxuICBsZWZ0U2VtaWpvaW4ocmlnaHQsIG9uKSB7XG4gICAgY29uc3QgZmlsdGVyUXVlcnkgPSBuZXcgX0Zyb21CdWlsZGVyKHJpZ2h0KTtcbiAgICBjb25zdCBqb2luQ29uZGl0aW9uID0gb24oXG4gICAgICB0aGlzLnRhYmxlLmluZGV4ZWRDb2xzLFxuICAgICAgcmlnaHQuaW5kZXhlZENvbHNcbiAgICApO1xuICAgIHJldHVybiBuZXcgU2VtaWpvaW5JbXBsKHRoaXMsIGZpbHRlclF1ZXJ5LCBqb2luQ29uZGl0aW9uKTtcbiAgfVxuICB0b1NxbCgpIHtcbiAgICByZXR1cm4gcmVuZGVyU2VsZWN0U3FsV2l0aEpvaW5zKHRoaXMudGFibGUsIHRoaXMud2hlcmVDbGF1c2UpO1xuICB9XG4gIGJ1aWxkKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG59O1xudmFyIFRhYmxlUmVmSW1wbCA9IGNsYXNzIHtcbiAgW1F1ZXJ5QnJhbmRdID0gdHJ1ZTtcbiAgdHlwZSA9IFwidGFibGVcIjtcbiAgc291cmNlTmFtZTtcbiAgYWNjZXNzb3JOYW1lO1xuICBjb2xzO1xuICBpbmRleGVkQ29scztcbiAgdGFibGVEZWY7XG4gIC8vIERlbGVnYXRlIFVudHlwZWRUYWJsZURlZiBwcm9wZXJ0aWVzIGZyb20gdGFibGVEZWYgc28gdGhpcyBjYW4gYmUgdXNlZCBhcyBhIHRhYmxlIGRlZi5cbiAgZ2V0IGNvbHVtbnMoKSB7XG4gICAgcmV0dXJuIHRoaXMudGFibGVEZWYuY29sdW1ucztcbiAgfVxuICBnZXQgaW5kZXhlcygpIHtcbiAgICByZXR1cm4gdGhpcy50YWJsZURlZi5pbmRleGVzO1xuICB9XG4gIGdldCByb3dUeXBlKCkge1xuICAgIHJldHVybiB0aGlzLnRhYmxlRGVmLnJvd1R5cGU7XG4gIH1cbiAgZ2V0IGNvbnN0cmFpbnRzKCkge1xuICAgIHJldHVybiB0aGlzLnRhYmxlRGVmLmNvbnN0cmFpbnRzO1xuICB9XG4gIGNvbnN0cnVjdG9yKHRhYmxlRGVmKSB7XG4gICAgdGhpcy5zb3VyY2VOYW1lID0gdGFibGVEZWYuc291cmNlTmFtZTtcbiAgICB0aGlzLmFjY2Vzc29yTmFtZSA9IHRhYmxlRGVmLmFjY2Vzc29yTmFtZTtcbiAgICB0aGlzLmNvbHMgPSBjcmVhdGVSb3dFeHByKHRhYmxlRGVmKTtcbiAgICB0aGlzLmluZGV4ZWRDb2xzID0gdGhpcy5jb2xzO1xuICAgIHRoaXMudGFibGVEZWYgPSB0YWJsZURlZjtcbiAgICBPYmplY3QuZnJlZXplKHRoaXMpO1xuICB9XG4gIGFzRnJvbSgpIHtcbiAgICByZXR1cm4gbmV3IEZyb21CdWlsZGVyKHRoaXMpO1xuICB9XG4gIHJpZ2h0U2VtaWpvaW4ob3RoZXIsIG9uKSB7XG4gICAgcmV0dXJuIHRoaXMuYXNGcm9tKCkucmlnaHRTZW1pam9pbihvdGhlciwgb24pO1xuICB9XG4gIGxlZnRTZW1pam9pbihvdGhlciwgb24pIHtcbiAgICByZXR1cm4gdGhpcy5hc0Zyb20oKS5sZWZ0U2VtaWpvaW4ob3RoZXIsIG9uKTtcbiAgfVxuICBidWlsZCgpIHtcbiAgICByZXR1cm4gdGhpcy5hc0Zyb20oKS5idWlsZCgpO1xuICB9XG4gIHRvU3FsKCkge1xuICAgIHJldHVybiB0aGlzLmFzRnJvbSgpLnRvU3FsKCk7XG4gIH1cbiAgd2hlcmUocHJlZGljYXRlKSB7XG4gICAgcmV0dXJuIHRoaXMuYXNGcm9tKCkud2hlcmUocHJlZGljYXRlKTtcbiAgfVxufTtcbmZ1bmN0aW9uIGNyZWF0ZVRhYmxlUmVmRnJvbURlZih0YWJsZURlZikge1xuICByZXR1cm4gbmV3IFRhYmxlUmVmSW1wbCh0YWJsZURlZik7XG59XG5mdW5jdGlvbiBtYWtlUXVlcnlCdWlsZGVyKHNjaGVtYTIpIHtcbiAgY29uc3QgcWIgPSAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgZm9yIChjb25zdCB0YWJsZTIgb2YgT2JqZWN0LnZhbHVlcyhzY2hlbWEyLnRhYmxlcykpIHtcbiAgICBjb25zdCByZWYgPSBjcmVhdGVUYWJsZVJlZkZyb21EZWYoXG4gICAgICB0YWJsZTJcbiAgICApO1xuICAgIHFiW3RhYmxlMi5hY2Nlc3Nvck5hbWVdID0gcmVmO1xuICB9XG4gIHJldHVybiBPYmplY3QuZnJlZXplKHFiKTtcbn1cbmZ1bmN0aW9uIGNyZWF0ZVJvd0V4cHIodGFibGVEZWYpIHtcbiAgY29uc3Qgcm93ID0ge307XG4gIGZvciAoY29uc3QgY29sdW1uTmFtZSBvZiBPYmplY3Qua2V5cyh0YWJsZURlZi5jb2x1bW5zKSkge1xuICAgIGNvbnN0IGNvbHVtbkJ1aWxkZXIgPSB0YWJsZURlZi5jb2x1bW5zW2NvbHVtbk5hbWVdO1xuICAgIGNvbnN0IGNvbHVtbiA9IG5ldyBDb2x1bW5FeHByZXNzaW9uKFxuICAgICAgdGFibGVEZWYuc291cmNlTmFtZSxcbiAgICAgIGNvbHVtbk5hbWUsXG4gICAgICBjb2x1bW5CdWlsZGVyLnR5cGVCdWlsZGVyLmFsZ2VicmFpY1R5cGUsXG4gICAgICBjb2x1bW5CdWlsZGVyLmNvbHVtbk1ldGFkYXRhLm5hbWVcbiAgICApO1xuICAgIHJvd1tjb2x1bW5OYW1lXSA9IE9iamVjdC5mcmVlemUoY29sdW1uKTtcbiAgfVxuICByZXR1cm4gT2JqZWN0LmZyZWV6ZShyb3cpO1xufVxuZnVuY3Rpb24gcmVuZGVyU2VsZWN0U3FsV2l0aEpvaW5zKHRhYmxlMiwgd2hlcmUsIGV4dHJhQ2xhdXNlcyA9IFtdKSB7XG4gIGNvbnN0IHF1b3RlZFRhYmxlID0gcXVvdGVJZGVudGlmaWVyKHRhYmxlMi5zb3VyY2VOYW1lKTtcbiAgY29uc3Qgc3FsID0gYFNFTEVDVCAqIEZST00gJHtxdW90ZWRUYWJsZX1gO1xuICBjb25zdCBjbGF1c2VzID0gW107XG4gIGlmICh3aGVyZSkgY2xhdXNlcy5wdXNoKGJvb2xlYW5FeHByVG9TcWwod2hlcmUpKTtcbiAgY2xhdXNlcy5wdXNoKC4uLmV4dHJhQ2xhdXNlcyk7XG4gIGlmIChjbGF1c2VzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHNxbDtcbiAgY29uc3Qgd2hlcmVTcWwgPSBjbGF1c2VzLmxlbmd0aCA9PT0gMSA/IGNsYXVzZXNbMF0gOiBjbGF1c2VzLm1hcCh3cmFwSW5QYXJlbnMpLmpvaW4oXCIgQU5EIFwiKTtcbiAgcmV0dXJuIGAke3NxbH0gV0hFUkUgJHt3aGVyZVNxbH1gO1xufVxudmFyIENvbHVtbkV4cHJlc3Npb24gPSBjbGFzcyB7XG4gIHR5cGUgPSBcImNvbHVtblwiO1xuICAvLyBUaGlzIGlzIHRoZSBjb2x1bW4gYWNjZXNzb3JcbiAgY29sdW1uO1xuICAvLyBUaGUgbmFtZSBvZiB0aGUgY29sdW1uIGluIHRoZSBkYXRhYmFzZS5cbiAgY29sdW1uTmFtZTtcbiAgdGFibGU7XG4gIC8vIHBoYW50b206IGFjdHVhbCBydW50aW1lIHZhbHVlIGlzIHVuZGVmaW5lZFxuICB0c1ZhbHVlVHlwZTtcbiAgc3BhY2V0aW1lVHlwZTtcbiAgY29uc3RydWN0b3IodGFibGUyLCBjb2x1bW4sIHNwYWNldGltZVR5cGUsIGNvbHVtbk5hbWUpIHtcbiAgICB0aGlzLnRhYmxlID0gdGFibGUyO1xuICAgIHRoaXMuY29sdW1uID0gY29sdW1uO1xuICAgIHRoaXMuY29sdW1uTmFtZSA9IGNvbHVtbk5hbWUgfHwgY29sdW1uO1xuICAgIHRoaXMuc3BhY2V0aW1lVHlwZSA9IHNwYWNldGltZVR5cGU7XG4gIH1cbiAgZXEoeCkge1xuICAgIHJldHVybiBuZXcgQm9vbGVhbkV4cHIoe1xuICAgICAgdHlwZTogXCJlcVwiLFxuICAgICAgbGVmdDogdGhpcyxcbiAgICAgIHJpZ2h0OiBub3JtYWxpemVWYWx1ZSh4KVxuICAgIH0pO1xuICB9XG4gIG5lKHgpIHtcbiAgICByZXR1cm4gbmV3IEJvb2xlYW5FeHByKHtcbiAgICAgIHR5cGU6IFwibmVcIixcbiAgICAgIGxlZnQ6IHRoaXMsXG4gICAgICByaWdodDogbm9ybWFsaXplVmFsdWUoeClcbiAgICB9KTtcbiAgfVxuICBsdCh4KSB7XG4gICAgcmV0dXJuIG5ldyBCb29sZWFuRXhwcih7XG4gICAgICB0eXBlOiBcImx0XCIsXG4gICAgICBsZWZ0OiB0aGlzLFxuICAgICAgcmlnaHQ6IG5vcm1hbGl6ZVZhbHVlKHgpXG4gICAgfSk7XG4gIH1cbiAgbHRlKHgpIHtcbiAgICByZXR1cm4gbmV3IEJvb2xlYW5FeHByKHtcbiAgICAgIHR5cGU6IFwibHRlXCIsXG4gICAgICBsZWZ0OiB0aGlzLFxuICAgICAgcmlnaHQ6IG5vcm1hbGl6ZVZhbHVlKHgpXG4gICAgfSk7XG4gIH1cbiAgZ3QoeCkge1xuICAgIHJldHVybiBuZXcgQm9vbGVhbkV4cHIoe1xuICAgICAgdHlwZTogXCJndFwiLFxuICAgICAgbGVmdDogdGhpcyxcbiAgICAgIHJpZ2h0OiBub3JtYWxpemVWYWx1ZSh4KVxuICAgIH0pO1xuICB9XG4gIGd0ZSh4KSB7XG4gICAgcmV0dXJuIG5ldyBCb29sZWFuRXhwcih7XG4gICAgICB0eXBlOiBcImd0ZVwiLFxuICAgICAgbGVmdDogdGhpcyxcbiAgICAgIHJpZ2h0OiBub3JtYWxpemVWYWx1ZSh4KVxuICAgIH0pO1xuICB9XG59O1xuZnVuY3Rpb24gbGl0ZXJhbCh2YWx1ZSkge1xuICByZXR1cm4geyB0eXBlOiBcImxpdGVyYWxcIiwgdmFsdWUgfTtcbn1cbmZ1bmN0aW9uIG5vcm1hbGl6ZVZhbHVlKHZhbCkge1xuICBpZiAodmFsLnR5cGUgPT09IFwibGl0ZXJhbFwiKVxuICAgIHJldHVybiB2YWw7XG4gIGlmICh0eXBlb2YgdmFsID09PSBcIm9iamVjdFwiICYmIHZhbCAhPSBudWxsICYmIFwidHlwZVwiIGluIHZhbCAmJiB2YWwudHlwZSA9PT0gXCJjb2x1bW5cIikge1xuICAgIHJldHVybiB2YWw7XG4gIH1cbiAgcmV0dXJuIGxpdGVyYWwodmFsKTtcbn1cbmZ1bmN0aW9uIG5vcm1hbGl6ZVByZWRpY2F0ZUV4cHIodmFsdWUpIHtcbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgQm9vbGVhbkV4cHIpIHJldHVybiB2YWx1ZTtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJib29sZWFuXCIpIHtcbiAgICByZXR1cm4gbmV3IEJvb2xlYW5FeHByKHtcbiAgICAgIHR5cGU6IFwiZXFcIixcbiAgICAgIGxlZnQ6IGxpdGVyYWwodmFsdWUpLFxuICAgICAgcmlnaHQ6IGxpdGVyYWwodHJ1ZSlcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gbmV3IEJvb2xlYW5FeHByKHtcbiAgICB0eXBlOiBcImVxXCIsXG4gICAgbGVmdDogdmFsdWUsXG4gICAgcmlnaHQ6IGxpdGVyYWwodHJ1ZSlcbiAgfSk7XG59XG52YXIgQm9vbGVhbkV4cHIgPSBjbGFzcyBfQm9vbGVhbkV4cHIge1xuICBjb25zdHJ1Y3RvcihkYXRhKSB7XG4gICAgdGhpcy5kYXRhID0gZGF0YTtcbiAgfVxuICBhbmQob3RoZXIpIHtcbiAgICByZXR1cm4gbmV3IF9Cb29sZWFuRXhwcih7XG4gICAgICB0eXBlOiBcImFuZFwiLFxuICAgICAgY2xhdXNlczogW3RoaXMuZGF0YSwgb3RoZXIuZGF0YV1cbiAgICB9KTtcbiAgfVxuICBvcihvdGhlcikge1xuICAgIHJldHVybiBuZXcgX0Jvb2xlYW5FeHByKHtcbiAgICAgIHR5cGU6IFwib3JcIixcbiAgICAgIGNsYXVzZXM6IFt0aGlzLmRhdGEsIG90aGVyLmRhdGFdXG4gICAgfSk7XG4gIH1cbiAgbm90KCkge1xuICAgIHJldHVybiBuZXcgX0Jvb2xlYW5FeHByKHsgdHlwZTogXCJub3RcIiwgY2xhdXNlOiB0aGlzLmRhdGEgfSk7XG4gIH1cbn07XG5mdW5jdGlvbiBub3QoY2xhdXNlKSB7XG4gIHJldHVybiBuZXcgQm9vbGVhbkV4cHIoeyB0eXBlOiBcIm5vdFwiLCBjbGF1c2U6IGNsYXVzZS5kYXRhIH0pO1xufVxuZnVuY3Rpb24gYW5kKGZpcnN0LCBzZWNvbmQsIC4uLnJlc3QpIHtcbiAgY29uc3QgY2xhdXNlcyA9IFtmaXJzdCwgc2Vjb25kLCAuLi5yZXN0XTtcbiAgcmV0dXJuIG5ldyBCb29sZWFuRXhwcih7XG4gICAgdHlwZTogXCJhbmRcIixcbiAgICBjbGF1c2VzOiBjbGF1c2VzLm1hcCgoYykgPT4gYy5kYXRhKVxuICB9KTtcbn1cbmZ1bmN0aW9uIG9yKGZpcnN0LCBzZWNvbmQsIC4uLnJlc3QpIHtcbiAgY29uc3QgY2xhdXNlcyA9IFtmaXJzdCwgc2Vjb25kLCAuLi5yZXN0XTtcbiAgcmV0dXJuIG5ldyBCb29sZWFuRXhwcih7XG4gICAgdHlwZTogXCJvclwiLFxuICAgIGNsYXVzZXM6IGNsYXVzZXMubWFwKChjKSA9PiBjLmRhdGEpXG4gIH0pO1xufVxuZnVuY3Rpb24gYm9vbGVhbkV4cHJUb1NxbChleHByLCB0YWJsZUFsaWFzKSB7XG4gIGNvbnN0IGRhdGEgPSBleHByIGluc3RhbmNlb2YgQm9vbGVhbkV4cHIgPyBleHByLmRhdGEgOiBleHByO1xuICBzd2l0Y2ggKGRhdGEudHlwZSkge1xuICAgIGNhc2UgXCJlcVwiOlxuICAgICAgcmV0dXJuIGAke3ZhbHVlRXhwclRvU3FsKGRhdGEubGVmdCl9ID0gJHt2YWx1ZUV4cHJUb1NxbChkYXRhLnJpZ2h0KX1gO1xuICAgIGNhc2UgXCJuZVwiOlxuICAgICAgcmV0dXJuIGAke3ZhbHVlRXhwclRvU3FsKGRhdGEubGVmdCl9IDw+ICR7dmFsdWVFeHByVG9TcWwoZGF0YS5yaWdodCl9YDtcbiAgICBjYXNlIFwiZ3RcIjpcbiAgICAgIHJldHVybiBgJHt2YWx1ZUV4cHJUb1NxbChkYXRhLmxlZnQpfSA+ICR7dmFsdWVFeHByVG9TcWwoZGF0YS5yaWdodCl9YDtcbiAgICBjYXNlIFwiZ3RlXCI6XG4gICAgICByZXR1cm4gYCR7dmFsdWVFeHByVG9TcWwoZGF0YS5sZWZ0KX0gPj0gJHt2YWx1ZUV4cHJUb1NxbChkYXRhLnJpZ2h0KX1gO1xuICAgIGNhc2UgXCJsdFwiOlxuICAgICAgcmV0dXJuIGAke3ZhbHVlRXhwclRvU3FsKGRhdGEubGVmdCl9IDwgJHt2YWx1ZUV4cHJUb1NxbChkYXRhLnJpZ2h0KX1gO1xuICAgIGNhc2UgXCJsdGVcIjpcbiAgICAgIHJldHVybiBgJHt2YWx1ZUV4cHJUb1NxbChkYXRhLmxlZnQpfSA8PSAke3ZhbHVlRXhwclRvU3FsKGRhdGEucmlnaHQpfWA7XG4gICAgY2FzZSBcImFuZFwiOlxuICAgICAgcmV0dXJuIGRhdGEuY2xhdXNlcy5tYXAoKGMpID0+IGJvb2xlYW5FeHByVG9TcWwoYykpLm1hcCh3cmFwSW5QYXJlbnMpLmpvaW4oXCIgQU5EIFwiKTtcbiAgICBjYXNlIFwib3JcIjpcbiAgICAgIHJldHVybiBkYXRhLmNsYXVzZXMubWFwKChjKSA9PiBib29sZWFuRXhwclRvU3FsKGMpKS5tYXAod3JhcEluUGFyZW5zKS5qb2luKFwiIE9SIFwiKTtcbiAgICBjYXNlIFwibm90XCI6XG4gICAgICByZXR1cm4gYE5PVCAke3dyYXBJblBhcmVucyhib29sZWFuRXhwclRvU3FsKGRhdGEuY2xhdXNlKSl9YDtcbiAgfVxufVxuZnVuY3Rpb24gd3JhcEluUGFyZW5zKHNxbCkge1xuICByZXR1cm4gYCgke3NxbH0pYDtcbn1cbmZ1bmN0aW9uIHZhbHVlRXhwclRvU3FsKGV4cHIsIHRhYmxlQWxpYXMpIHtcbiAgaWYgKGlzTGl0ZXJhbEV4cHIoZXhwcikpIHtcbiAgICByZXR1cm4gbGl0ZXJhbFZhbHVlVG9TcWwoZXhwci52YWx1ZSk7XG4gIH1cbiAgY29uc3QgdGFibGUyID0gZXhwci50YWJsZTtcbiAgcmV0dXJuIGAke3F1b3RlSWRlbnRpZmllcih0YWJsZTIpfS4ke3F1b3RlSWRlbnRpZmllcihleHByLmNvbHVtbk5hbWUpfWA7XG59XG5mdW5jdGlvbiBsaXRlcmFsVmFsdWVUb1NxbCh2YWx1ZSkge1xuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHZvaWQgMCkge1xuICAgIHJldHVybiBcIk5VTExcIjtcbiAgfVxuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBJZGVudGl0eSB8fCB2YWx1ZSBpbnN0YW5jZW9mIENvbm5lY3Rpb25JZCkge1xuICAgIHJldHVybiBgMHgke3ZhbHVlLnRvSGV4U3RyaW5nKCl9YDtcbiAgfVxuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBUaW1lc3RhbXApIHtcbiAgICByZXR1cm4gYCcke3ZhbHVlLnRvSVNPU3RyaW5nKCl9J2A7XG4gIH1cbiAgc3dpdGNoICh0eXBlb2YgdmFsdWUpIHtcbiAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgY2FzZSBcImJpZ2ludFwiOlxuICAgICAgcmV0dXJuIFN0cmluZyh2YWx1ZSk7XG4gICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICAgIHJldHVybiB2YWx1ZSA/IFwiVFJVRVwiIDogXCJGQUxTRVwiO1xuICAgIGNhc2UgXCJzdHJpbmdcIjpcbiAgICAgIHJldHVybiBgJyR7dmFsdWUucmVwbGFjZSgvJy9nLCBcIicnXCIpfSdgO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gYCcke0pTT04uc3RyaW5naWZ5KHZhbHVlKS5yZXBsYWNlKC8nL2csIFwiJydcIil9J2A7XG4gIH1cbn1cbmZ1bmN0aW9uIHF1b3RlSWRlbnRpZmllcihuYW1lKSB7XG4gIHJldHVybiBgXCIke25hbWUucmVwbGFjZSgvXCIvZywgJ1wiXCInKX1cImA7XG59XG5mdW5jdGlvbiBpc0xpdGVyYWxFeHByKGV4cHIpIHtcbiAgcmV0dXJuIGV4cHIudHlwZSA9PT0gXCJsaXRlcmFsXCI7XG59XG5mdW5jdGlvbiBldmFsdWF0ZUJvb2xlYW5FeHByKGV4cHIsIHJvdykge1xuICByZXR1cm4gZXZhbHVhdGVEYXRhKGV4cHIuZGF0YSwgcm93KTtcbn1cbmZ1bmN0aW9uIGV2YWx1YXRlRGF0YShkYXRhLCByb3cpIHtcbiAgc3dpdGNoIChkYXRhLnR5cGUpIHtcbiAgICBjYXNlIFwiZXFcIjpcbiAgICAgIHJldHVybiByZXNvbHZlVmFsdWUoZGF0YS5sZWZ0LCByb3cpID09PSByZXNvbHZlVmFsdWUoZGF0YS5yaWdodCwgcm93KTtcbiAgICBjYXNlIFwibmVcIjpcbiAgICAgIHJldHVybiByZXNvbHZlVmFsdWUoZGF0YS5sZWZ0LCByb3cpICE9PSByZXNvbHZlVmFsdWUoZGF0YS5yaWdodCwgcm93KTtcbiAgICBjYXNlIFwiZ3RcIjpcbiAgICAgIHJldHVybiByZXNvbHZlVmFsdWUoZGF0YS5sZWZ0LCByb3cpID4gcmVzb2x2ZVZhbHVlKGRhdGEucmlnaHQsIHJvdyk7XG4gICAgY2FzZSBcImd0ZVwiOlxuICAgICAgcmV0dXJuIHJlc29sdmVWYWx1ZShkYXRhLmxlZnQsIHJvdykgPj0gcmVzb2x2ZVZhbHVlKGRhdGEucmlnaHQsIHJvdyk7XG4gICAgY2FzZSBcImx0XCI6XG4gICAgICByZXR1cm4gcmVzb2x2ZVZhbHVlKGRhdGEubGVmdCwgcm93KSA8IHJlc29sdmVWYWx1ZShkYXRhLnJpZ2h0LCByb3cpO1xuICAgIGNhc2UgXCJsdGVcIjpcbiAgICAgIHJldHVybiByZXNvbHZlVmFsdWUoZGF0YS5sZWZ0LCByb3cpIDw9IHJlc29sdmVWYWx1ZShkYXRhLnJpZ2h0LCByb3cpO1xuICAgIGNhc2UgXCJhbmRcIjpcbiAgICAgIHJldHVybiBkYXRhLmNsYXVzZXMuZXZlcnkoKGMpID0+IGV2YWx1YXRlRGF0YShjLCByb3cpKTtcbiAgICBjYXNlIFwib3JcIjpcbiAgICAgIHJldHVybiBkYXRhLmNsYXVzZXMuc29tZSgoYykgPT4gZXZhbHVhdGVEYXRhKGMsIHJvdykpO1xuICAgIGNhc2UgXCJub3RcIjpcbiAgICAgIHJldHVybiAhZXZhbHVhdGVEYXRhKGRhdGEuY2xhdXNlLCByb3cpO1xuICB9XG59XG5mdW5jdGlvbiByZXNvbHZlVmFsdWUoZXhwciwgcm93KSB7XG4gIGlmIChpc0xpdGVyYWxFeHByKGV4cHIpKSB7XG4gICAgcmV0dXJuIHRvQ29tcGFyYWJsZVZhbHVlKGV4cHIudmFsdWUpO1xuICB9XG4gIHJldHVybiB0b0NvbXBhcmFibGVWYWx1ZShyb3dbZXhwci5jb2x1bW5dKTtcbn1cbmZ1bmN0aW9uIGlzSGV4U2VyaWFsaXphYmxlTGlrZSh2YWx1ZSkge1xuICByZXR1cm4gISF2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHZhbHVlLnRvSGV4U3RyaW5nID09PSBcImZ1bmN0aW9uXCI7XG59XG5mdW5jdGlvbiBpc1RpbWVzdGFtcExpa2UodmFsdWUpIHtcbiAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIpIHJldHVybiBmYWxzZTtcbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgVGltZXN0YW1wKSByZXR1cm4gdHJ1ZTtcbiAgY29uc3QgbWljcm9zID0gdmFsdWVbXCJfX3RpbWVzdGFtcF9taWNyb3Nfc2luY2VfdW5peF9lcG9jaF9fXCJdO1xuICByZXR1cm4gdHlwZW9mIG1pY3JvcyA9PT0gXCJiaWdpbnRcIjtcbn1cbmZ1bmN0aW9uIHRvQ29tcGFyYWJsZVZhbHVlKHZhbHVlKSB7XG4gIGlmIChpc0hleFNlcmlhbGl6YWJsZUxpa2UodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlLnRvSGV4U3RyaW5nKCk7XG4gIH1cbiAgaWYgKGlzVGltZXN0YW1wTGlrZSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gdmFsdWUuX190aW1lc3RhbXBfbWljcm9zX3NpbmNlX3VuaXhfZXBvY2hfXztcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5mdW5jdGlvbiBnZXRRdWVyeVRhYmxlTmFtZShxdWVyeSkge1xuICBpZiAocXVlcnkudGFibGUpIHJldHVybiBxdWVyeS50YWJsZS5uYW1lO1xuICBpZiAocXVlcnkubmFtZSkgcmV0dXJuIHF1ZXJ5Lm5hbWU7XG4gIGlmIChxdWVyeS5zb3VyY2VRdWVyeSkgcmV0dXJuIHF1ZXJ5LnNvdXJjZVF1ZXJ5LnRhYmxlLm5hbWU7XG4gIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBleHRyYWN0IHRhYmxlIG5hbWUgZnJvbSBxdWVyeVwiKTtcbn1cbmZ1bmN0aW9uIGdldFF1ZXJ5QWNjZXNzb3JOYW1lKHF1ZXJ5KSB7XG4gIGlmIChxdWVyeS50YWJsZSkgcmV0dXJuIHF1ZXJ5LnRhYmxlLmFjY2Vzc29yTmFtZTtcbiAgaWYgKHF1ZXJ5LmFjY2Vzc29yTmFtZSkgcmV0dXJuIHF1ZXJ5LmFjY2Vzc29yTmFtZTtcbiAgaWYgKHF1ZXJ5LnNvdXJjZVF1ZXJ5KSByZXR1cm4gcXVlcnkuc291cmNlUXVlcnkudGFibGUuYWNjZXNzb3JOYW1lO1xuICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgZXh0cmFjdCBhY2Nlc3NvciBuYW1lIGZyb20gcXVlcnlcIik7XG59XG5mdW5jdGlvbiBnZXRRdWVyeVdoZXJlQ2xhdXNlKHF1ZXJ5KSB7XG4gIGlmIChxdWVyeS53aGVyZUNsYXVzZSkgcmV0dXJuIHF1ZXJ5LndoZXJlQ2xhdXNlO1xuICByZXR1cm4gdm9pZCAwO1xufVxuXG4vLyBzcmMvc2VydmVyL3ZpZXdzLnRzXG5mdW5jdGlvbiBtYWtlVmlld0V4cG9ydChjdHgsIG9wdHMsIHBhcmFtcywgcmV0LCBmbikge1xuICBjb25zdCB2aWV3RXhwb3J0ID0gKFxuICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgdHlwZXNjcmlwdCBpbmNvcnJlY3RseSBzYXlzIEZ1bmN0aW9uI2JpbmQgcmVxdWlyZXMgYW4gYXJndW1lbnQuXG4gICAgZm4uYmluZCgpXG4gICk7XG4gIHZpZXdFeHBvcnRbZXhwb3J0Q29udGV4dF0gPSBjdHg7XG4gIHZpZXdFeHBvcnRbcmVnaXN0ZXJFeHBvcnRdID0gKGN0eDIsIGV4cG9ydE5hbWUpID0+IHtcbiAgICByZWdpc3RlclZpZXcoY3R4Miwgb3B0cywgZXhwb3J0TmFtZSwgZmFsc2UsIHBhcmFtcywgcmV0LCBmbik7XG4gIH07XG4gIHJldHVybiB2aWV3RXhwb3J0O1xufVxuZnVuY3Rpb24gbWFrZUFub25WaWV3RXhwb3J0KGN0eCwgb3B0cywgcGFyYW1zLCByZXQsIGZuKSB7XG4gIGNvbnN0IHZpZXdFeHBvcnQgPSAoXG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvciB0eXBlc2NyaXB0IGluY29ycmVjdGx5IHNheXMgRnVuY3Rpb24jYmluZCByZXF1aXJlcyBhbiBhcmd1bWVudC5cbiAgICBmbi5iaW5kKClcbiAgKTtcbiAgdmlld0V4cG9ydFtleHBvcnRDb250ZXh0XSA9IGN0eDtcbiAgdmlld0V4cG9ydFtyZWdpc3RlckV4cG9ydF0gPSAoY3R4MiwgZXhwb3J0TmFtZSkgPT4ge1xuICAgIHJlZ2lzdGVyVmlldyhjdHgyLCBvcHRzLCBleHBvcnROYW1lLCB0cnVlLCBwYXJhbXMsIHJldCwgZm4pO1xuICB9O1xuICByZXR1cm4gdmlld0V4cG9ydDtcbn1cbmZ1bmN0aW9uIHJlZ2lzdGVyVmlldyhjdHgsIG9wdHMsIGV4cG9ydE5hbWUsIGFub24sIHBhcmFtcywgcmV0LCBmbikge1xuICBjb25zdCBwYXJhbXNCdWlsZGVyID0gbmV3IFJvd0J1aWxkZXIocGFyYW1zLCB0b1Bhc2NhbENhc2UoZXhwb3J0TmFtZSkpO1xuICBsZXQgcmV0dXJuVHlwZSA9IGN0eC5yZWdpc3RlclR5cGVzUmVjdXJzaXZlbHkocmV0KS5hbGdlYnJhaWNUeXBlO1xuICBjb25zdCB7IHR5cGVzcGFjZSB9ID0gY3R4O1xuICBjb25zdCB7IHZhbHVlOiBwYXJhbVR5cGUgfSA9IGN0eC5yZXNvbHZlVHlwZShcbiAgICBjdHgucmVnaXN0ZXJUeXBlc1JlY3Vyc2l2ZWx5KHBhcmFtc0J1aWxkZXIpXG4gICk7XG4gIGN0eC5tb2R1bGVEZWYudmlld3MucHVzaCh7XG4gICAgc291cmNlTmFtZTogZXhwb3J0TmFtZSxcbiAgICBpbmRleDogKGFub24gPyBjdHguYW5vblZpZXdzIDogY3R4LnZpZXdzKS5sZW5ndGgsXG4gICAgaXNQdWJsaWM6IG9wdHMucHVibGljLFxuICAgIGlzQW5vbnltb3VzOiBhbm9uLFxuICAgIHBhcmFtczogcGFyYW1UeXBlLFxuICAgIHJldHVyblR5cGVcbiAgfSk7XG4gIGlmIChvcHRzLm5hbWUgIT0gbnVsbCkge1xuICAgIGN0eC5tb2R1bGVEZWYuZXhwbGljaXROYW1lcy5lbnRyaWVzLnB1c2goe1xuICAgICAgdGFnOiBcIkZ1bmN0aW9uXCIsXG4gICAgICB2YWx1ZToge1xuICAgICAgICBzb3VyY2VOYW1lOiBleHBvcnROYW1lLFxuICAgICAgICBjYW5vbmljYWxOYW1lOiBvcHRzLm5hbWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICBpZiAocmV0dXJuVHlwZS50YWcgPT0gXCJTdW1cIikge1xuICAgIGNvbnN0IG9yaWdpbmFsRm4gPSBmbjtcbiAgICBmbiA9ICgoY3R4MiwgYXJncykgPT4ge1xuICAgICAgY29uc3QgcmV0MiA9IG9yaWdpbmFsRm4oY3R4MiwgYXJncyk7XG4gICAgICByZXR1cm4gcmV0MiA9PSBudWxsID8gW10gOiBbcmV0Ml07XG4gICAgfSk7XG4gICAgcmV0dXJuVHlwZSA9IEFsZ2VicmFpY1R5cGUuQXJyYXkoXG4gICAgICByZXR1cm5UeXBlLnZhbHVlLnZhcmlhbnRzWzBdLmFsZ2VicmFpY1R5cGVcbiAgICApO1xuICB9XG4gIChhbm9uID8gY3R4LmFub25WaWV3cyA6IGN0eC52aWV3cykucHVzaCh7XG4gICAgZm4sXG4gICAgZGVzZXJpYWxpemVQYXJhbXM6IFByb2R1Y3RUeXBlLm1ha2VEZXNlcmlhbGl6ZXIocGFyYW1UeXBlLCB0eXBlc3BhY2UpLFxuICAgIHNlcmlhbGl6ZVJldHVybjogQWxnZWJyYWljVHlwZS5tYWtlU2VyaWFsaXplcihyZXR1cm5UeXBlLCB0eXBlc3BhY2UpLFxuICAgIHJldHVyblR5cGVCYXNlU2l6ZTogYnNhdG5CYXNlU2l6ZSh0eXBlc3BhY2UsIHJldHVyblR5cGUpXG4gIH0pO1xufVxuXG4vLyBzcmMvbGliL2Vycm9ycy50c1xudmFyIFNlbmRlckVycm9yID0gY2xhc3MgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2UpIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgfVxuICBnZXQgbmFtZSgpIHtcbiAgICByZXR1cm4gXCJTZW5kZXJFcnJvclwiO1xuICB9XG59O1xuXG4vLyBzcmMvc2VydmVyL2Vycm9ycy50c1xudmFyIFNwYWNldGltZUhvc3RFcnJvciA9IGNsYXNzIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gIH1cbiAgZ2V0IG5hbWUoKSB7XG4gICAgcmV0dXJuIFwiU3BhY2V0aW1lSG9zdEVycm9yXCI7XG4gIH1cbn07XG52YXIgZXJyb3JEYXRhID0ge1xuICAvKipcbiAgICogQSBnZW5lcmljIGVycm9yIGNsYXNzIGZvciB1bmtub3duIGVycm9yIGNvZGVzLlxuICAgKi9cbiAgSG9zdENhbGxGYWlsdXJlOiAxLFxuICAvKipcbiAgICogRXJyb3IgaW5kaWNhdGluZyB0aGF0IGFuIEFCSSBjYWxsIHdhcyBtYWRlIG91dHNpZGUgb2YgYSB0cmFuc2FjdGlvbi5cbiAgICovXG4gIE5vdEluVHJhbnNhY3Rpb246IDIsXG4gIC8qKlxuICAgKiBFcnJvciBpbmRpY2F0aW5nIHRoYXQgQlNBVE4gZGVjb2RpbmcgZmFpbGVkLlxuICAgKiBUaGlzIHR5cGljYWxseSBtZWFucyB0aGF0IHRoZSBkYXRhIGNvdWxkIG5vdCBiZSBkZWNvZGVkIHRvIHRoZSBleHBlY3RlZCB0eXBlLlxuICAgKi9cbiAgQnNhdG5EZWNvZGVFcnJvcjogMyxcbiAgLyoqXG4gICAqIEVycm9yIGluZGljYXRpbmcgdGhhdCBhIHNwZWNpZmllZCB0YWJsZSBkb2VzIG5vdCBleGlzdC5cbiAgICovXG4gIE5vU3VjaFRhYmxlOiA0LFxuICAvKipcbiAgICogRXJyb3IgaW5kaWNhdGluZyB0aGF0IGEgc3BlY2lmaWVkIGluZGV4IGRvZXMgbm90IGV4aXN0LlxuICAgKi9cbiAgTm9TdWNoSW5kZXg6IDUsXG4gIC8qKlxuICAgKiBFcnJvciBpbmRpY2F0aW5nIHRoYXQgYSBzcGVjaWZpZWQgcm93IGl0ZXJhdG9yIGlzIG5vdCB2YWxpZC5cbiAgICovXG4gIE5vU3VjaEl0ZXI6IDYsXG4gIC8qKlxuICAgKiBFcnJvciBpbmRpY2F0aW5nIHRoYXQgYSBzcGVjaWZpZWQgY29uc29sZSB0aW1lciBkb2VzIG5vdCBleGlzdC5cbiAgICovXG4gIE5vU3VjaENvbnNvbGVUaW1lcjogNyxcbiAgLyoqXG4gICAqIEVycm9yIGluZGljYXRpbmcgdGhhdCBhIHNwZWNpZmllZCBieXRlcyBzb3VyY2Ugb3Igc2luayBpcyBub3QgdmFsaWQuXG4gICAqL1xuICBOb1N1Y2hCeXRlczogOCxcbiAgLyoqXG4gICAqIEVycm9yIGluZGljYXRpbmcgdGhhdCBhIHByb3ZpZGVkIHNpbmsgaGFzIG5vIG1vcmUgc3BhY2UgbGVmdC5cbiAgICovXG4gIE5vU3BhY2U6IDksXG4gIC8qKlxuICAgKiBFcnJvciBpbmRpY2F0aW5nIHRoYXQgdGhlcmUgaXMgbm8gbW9yZSBzcGFjZSBpbiB0aGUgZGF0YWJhc2UuXG4gICAqL1xuICBCdWZmZXJUb29TbWFsbDogMTEsXG4gIC8qKlxuICAgKiBFcnJvciBpbmRpY2F0aW5nIHRoYXQgYSB2YWx1ZSB3aXRoIGEgZ2l2ZW4gdW5pcXVlIGlkZW50aWZpZXIgYWxyZWFkeSBleGlzdHMuXG4gICAqL1xuICBVbmlxdWVBbHJlYWR5RXhpc3RzOiAxMixcbiAgLyoqXG4gICAqIEVycm9yIGluZGljYXRpbmcgdGhhdCB0aGUgc3BlY2lmaWVkIGRlbGF5IGluIHNjaGVkdWxpbmcgYSByb3cgd2FzIHRvbyBsb25nLlxuICAgKi9cbiAgU2NoZWR1bGVBdERlbGF5VG9vTG9uZzogMTMsXG4gIC8qKlxuICAgKiBFcnJvciBpbmRpY2F0aW5nIHRoYXQgYW4gaW5kZXggd2FzIG5vdCB1bmlxdWUgd2hlbiBpdCB3YXMgZXhwZWN0ZWQgdG8gYmUuXG4gICAqL1xuICBJbmRleE5vdFVuaXF1ZTogMTQsXG4gIC8qKlxuICAgKiBFcnJvciBpbmRpY2F0aW5nIHRoYXQgYW4gaW5kZXggd2FzIG5vdCB1bmlxdWUgd2hlbiBpdCB3YXMgZXhwZWN0ZWQgdG8gYmUuXG4gICAqL1xuICBOb1N1Y2hSb3c6IDE1LFxuICAvKipcbiAgICogRXJyb3IgaW5kaWNhdGluZyB0aGF0IGFuIGF1dG8taW5jcmVtZW50IHNlcXVlbmNlIGhhcyBvdmVyZmxvd2VkLlxuICAgKi9cbiAgQXV0b0luY092ZXJmbG93OiAxNixcbiAgV291bGRCbG9ja1RyYW5zYWN0aW9uOiAxNyxcbiAgVHJhbnNhY3Rpb25Ob3RBbm9ueW1vdXM6IDE4LFxuICBUcmFuc2FjdGlvbklzUmVhZE9ubHk6IDE5LFxuICBUcmFuc2FjdGlvbklzTXV0OiAyMCxcbiAgSHR0cEVycm9yOiAyMVxufTtcbmZ1bmN0aW9uIG1hcEVudHJpZXMoeCwgZikge1xuICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgIE9iamVjdC5lbnRyaWVzKHgpLm1hcCgoW2ssIHZdKSA9PiBbaywgZihrLCB2KV0pXG4gICk7XG59XG52YXIgZXJybm9Ub0NsYXNzID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTtcbnZhciBlcnJvcnMgPSBPYmplY3QuZnJlZXplKFxuICBtYXBFbnRyaWVzKGVycm9yRGF0YSwgKG5hbWUsIGNvZGUpID0+IHtcbiAgICBjb25zdCBjbHMgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkoXG4gICAgICBjbGFzcyBleHRlbmRzIFNwYWNldGltZUhvc3RFcnJvciB7XG4gICAgICAgIGdldCBuYW1lKCkge1xuICAgICAgICAgIHJldHVybiBuYW1lO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgXCJuYW1lXCIsXG4gICAgICB7IHZhbHVlOiBuYW1lLCB3cml0YWJsZTogZmFsc2UgfVxuICAgICk7XG4gICAgZXJybm9Ub0NsYXNzLnNldChjb2RlLCBjbHMpO1xuICAgIHJldHVybiBjbHM7XG4gIH0pXG4pO1xuZnVuY3Rpb24gZ2V0RXJyb3JDb25zdHJ1Y3Rvcihjb2RlKSB7XG4gIHJldHVybiBlcnJub1RvQ2xhc3MuZ2V0KGNvZGUpID8/IFNwYWNldGltZUhvc3RFcnJvcjtcbn1cblxuLy8gLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3B1cmUtcmFuZEA3LjAuMS9ub2RlX21vZHVsZXMvcHVyZS1yYW5kL2xpYi9lc20vZGlzdHJpYnV0aW9uL1Vuc2FmZVVuaWZvcm1CaWdJbnREaXN0cmlidXRpb24uanNcbnZhciBTQmlnSW50ID0gdHlwZW9mIEJpZ0ludCAhPT0gXCJ1bmRlZmluZWRcIiA/IEJpZ0ludCA6IHZvaWQgMDtcbnZhciBPbmUgPSB0eXBlb2YgQmlnSW50ICE9PSBcInVuZGVmaW5lZFwiID8gQmlnSW50KDEpIDogdm9pZCAwO1xudmFyIFRoaXJ0eVR3byA9IHR5cGVvZiBCaWdJbnQgIT09IFwidW5kZWZpbmVkXCIgPyBCaWdJbnQoMzIpIDogdm9pZCAwO1xudmFyIE51bVZhbHVlcyA9IHR5cGVvZiBCaWdJbnQgIT09IFwidW5kZWZpbmVkXCIgPyBCaWdJbnQoNDI5NDk2NzI5NikgOiB2b2lkIDA7XG5mdW5jdGlvbiB1bnNhZmVVbmlmb3JtQmlnSW50RGlzdHJpYnV0aW9uKGZyb20sIHRvLCBybmcpIHtcbiAgdmFyIGRpZmYgPSB0byAtIGZyb20gKyBPbmU7XG4gIHZhciBGaW5hbE51bVZhbHVlcyA9IE51bVZhbHVlcztcbiAgdmFyIE51bUl0ZXJhdGlvbnMgPSAxO1xuICB3aGlsZSAoRmluYWxOdW1WYWx1ZXMgPCBkaWZmKSB7XG4gICAgRmluYWxOdW1WYWx1ZXMgPDw9IFRoaXJ0eVR3bztcbiAgICArK051bUl0ZXJhdGlvbnM7XG4gIH1cbiAgdmFyIHZhbHVlID0gZ2VuZXJhdGVOZXh0KE51bUl0ZXJhdGlvbnMsIHJuZyk7XG4gIGlmICh2YWx1ZSA8IGRpZmYpIHtcbiAgICByZXR1cm4gdmFsdWUgKyBmcm9tO1xuICB9XG4gIGlmICh2YWx1ZSArIGRpZmYgPCBGaW5hbE51bVZhbHVlcykge1xuICAgIHJldHVybiB2YWx1ZSAlIGRpZmYgKyBmcm9tO1xuICB9XG4gIHZhciBNYXhBY2NlcHRlZFJhbmRvbSA9IEZpbmFsTnVtVmFsdWVzIC0gRmluYWxOdW1WYWx1ZXMgJSBkaWZmO1xuICB3aGlsZSAodmFsdWUgPj0gTWF4QWNjZXB0ZWRSYW5kb20pIHtcbiAgICB2YWx1ZSA9IGdlbmVyYXRlTmV4dChOdW1JdGVyYXRpb25zLCBybmcpO1xuICB9XG4gIHJldHVybiB2YWx1ZSAlIGRpZmYgKyBmcm9tO1xufVxuZnVuY3Rpb24gZ2VuZXJhdGVOZXh0KE51bUl0ZXJhdGlvbnMsIHJuZykge1xuICB2YXIgdmFsdWUgPSBTQmlnSW50KHJuZy51bnNhZmVOZXh0KCkgKyAyMTQ3NDgzNjQ4KTtcbiAgZm9yICh2YXIgbnVtID0gMTsgbnVtIDwgTnVtSXRlcmF0aW9uczsgKytudW0pIHtcbiAgICB2YXIgb3V0ID0gcm5nLnVuc2FmZU5leHQoKTtcbiAgICB2YWx1ZSA9ICh2YWx1ZSA8PCBUaGlydHlUd28pICsgU0JpZ0ludChvdXQgKyAyMTQ3NDgzNjQ4KTtcbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbi8vIC4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9wdXJlLXJhbmRANy4wLjEvbm9kZV9tb2R1bGVzL3B1cmUtcmFuZC9saWIvZXNtL2Rpc3RyaWJ1dGlvbi9pbnRlcm5hbHMvVW5zYWZlVW5pZm9ybUludERpc3RyaWJ1dGlvbkludGVybmFsLmpzXG5mdW5jdGlvbiB1bnNhZmVVbmlmb3JtSW50RGlzdHJpYnV0aW9uSW50ZXJuYWwocmFuZ2VTaXplLCBybmcpIHtcbiAgdmFyIE1heEFsbG93ZWQgPSByYW5nZVNpemUgPiAyID8gfn4oNDI5NDk2NzI5NiAvIHJhbmdlU2l6ZSkgKiByYW5nZVNpemUgOiA0Mjk0OTY3Mjk2O1xuICB2YXIgZGVsdGFWID0gcm5nLnVuc2FmZU5leHQoKSArIDIxNDc0ODM2NDg7XG4gIHdoaWxlIChkZWx0YVYgPj0gTWF4QWxsb3dlZCkge1xuICAgIGRlbHRhViA9IHJuZy51bnNhZmVOZXh0KCkgKyAyMTQ3NDgzNjQ4O1xuICB9XG4gIHJldHVybiBkZWx0YVYgJSByYW5nZVNpemU7XG59XG5cbi8vIC4uLy4uL25vZGVfbW9kdWxlcy8ucG5wbS9wdXJlLXJhbmRANy4wLjEvbm9kZV9tb2R1bGVzL3B1cmUtcmFuZC9saWIvZXNtL2Rpc3RyaWJ1dGlvbi9pbnRlcm5hbHMvQXJyYXlJbnQ2NC5qc1xuZnVuY3Rpb24gZnJvbU51bWJlclRvQXJyYXlJbnQ2NChvdXQsIG4pIHtcbiAgaWYgKG4gPCAwKSB7XG4gICAgdmFyIHBvc04gPSAtbjtcbiAgICBvdXQuc2lnbiA9IC0xO1xuICAgIG91dC5kYXRhWzBdID0gfn4ocG9zTiAvIDQyOTQ5NjcyOTYpO1xuICAgIG91dC5kYXRhWzFdID0gcG9zTiA+Pj4gMDtcbiAgfSBlbHNlIHtcbiAgICBvdXQuc2lnbiA9IDE7XG4gICAgb3V0LmRhdGFbMF0gPSB+fihuIC8gNDI5NDk2NzI5Nik7XG4gICAgb3V0LmRhdGFbMV0gPSBuID4+PiAwO1xuICB9XG4gIHJldHVybiBvdXQ7XG59XG5mdW5jdGlvbiBzdWJzdHJhY3RBcnJheUludDY0KG91dCwgYXJyYXlJbnRBLCBhcnJheUludEIpIHtcbiAgdmFyIGxvd0EgPSBhcnJheUludEEuZGF0YVsxXTtcbiAgdmFyIGhpZ2hBID0gYXJyYXlJbnRBLmRhdGFbMF07XG4gIHZhciBzaWduQSA9IGFycmF5SW50QS5zaWduO1xuICB2YXIgbG93QiA9IGFycmF5SW50Qi5kYXRhWzFdO1xuICB2YXIgaGlnaEIgPSBhcnJheUludEIuZGF0YVswXTtcbiAgdmFyIHNpZ25CID0gYXJyYXlJbnRCLnNpZ247XG4gIG91dC5zaWduID0gMTtcbiAgaWYgKHNpZ25BID09PSAxICYmIHNpZ25CID09PSAtMSkge1xuICAgIHZhciBsb3dfMSA9IGxvd0EgKyBsb3dCO1xuICAgIHZhciBoaWdoID0gaGlnaEEgKyBoaWdoQiArIChsb3dfMSA+IDQyOTQ5NjcyOTUgPyAxIDogMCk7XG4gICAgb3V0LmRhdGFbMF0gPSBoaWdoID4+PiAwO1xuICAgIG91dC5kYXRhWzFdID0gbG93XzEgPj4+IDA7XG4gICAgcmV0dXJuIG91dDtcbiAgfVxuICB2YXIgbG93Rmlyc3QgPSBsb3dBO1xuICB2YXIgaGlnaEZpcnN0ID0gaGlnaEE7XG4gIHZhciBsb3dTZWNvbmQgPSBsb3dCO1xuICB2YXIgaGlnaFNlY29uZCA9IGhpZ2hCO1xuICBpZiAoc2lnbkEgPT09IC0xKSB7XG4gICAgbG93Rmlyc3QgPSBsb3dCO1xuICAgIGhpZ2hGaXJzdCA9IGhpZ2hCO1xuICAgIGxvd1NlY29uZCA9IGxvd0E7XG4gICAgaGlnaFNlY29uZCA9IGhpZ2hBO1xuICB9XG4gIHZhciByZW1pbmRlckxvdyA9IDA7XG4gIHZhciBsb3cgPSBsb3dGaXJzdCAtIGxvd1NlY29uZDtcbiAgaWYgKGxvdyA8IDApIHtcbiAgICByZW1pbmRlckxvdyA9IDE7XG4gICAgbG93ID0gbG93ID4+PiAwO1xuICB9XG4gIG91dC5kYXRhWzBdID0gaGlnaEZpcnN0IC0gaGlnaFNlY29uZCAtIHJlbWluZGVyTG93O1xuICBvdXQuZGF0YVsxXSA9IGxvdztcbiAgcmV0dXJuIG91dDtcbn1cblxuLy8gLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3B1cmUtcmFuZEA3LjAuMS9ub2RlX21vZHVsZXMvcHVyZS1yYW5kL2xpYi9lc20vZGlzdHJpYnV0aW9uL2ludGVybmFscy9VbnNhZmVVbmlmb3JtQXJyYXlJbnREaXN0cmlidXRpb25JbnRlcm5hbC5qc1xuZnVuY3Rpb24gdW5zYWZlVW5pZm9ybUFycmF5SW50RGlzdHJpYnV0aW9uSW50ZXJuYWwob3V0LCByYW5nZVNpemUsIHJuZykge1xuICB2YXIgcmFuZ2VMZW5ndGggPSByYW5nZVNpemUubGVuZ3RoO1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIGZvciAodmFyIGluZGV4ID0gMDsgaW5kZXggIT09IHJhbmdlTGVuZ3RoOyArK2luZGV4KSB7XG4gICAgICB2YXIgaW5kZXhSYW5nZVNpemUgPSBpbmRleCA9PT0gMCA/IHJhbmdlU2l6ZVswXSArIDEgOiA0Mjk0OTY3Mjk2O1xuICAgICAgdmFyIGcgPSB1bnNhZmVVbmlmb3JtSW50RGlzdHJpYnV0aW9uSW50ZXJuYWwoaW5kZXhSYW5nZVNpemUsIHJuZyk7XG4gICAgICBvdXRbaW5kZXhdID0gZztcbiAgICB9XG4gICAgZm9yICh2YXIgaW5kZXggPSAwOyBpbmRleCAhPT0gcmFuZ2VMZW5ndGg7ICsraW5kZXgpIHtcbiAgICAgIHZhciBjdXJyZW50ID0gb3V0W2luZGV4XTtcbiAgICAgIHZhciBjdXJyZW50SW5SYW5nZSA9IHJhbmdlU2l6ZVtpbmRleF07XG4gICAgICBpZiAoY3VycmVudCA8IGN1cnJlbnRJblJhbmdlKSB7XG4gICAgICAgIHJldHVybiBvdXQ7XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnQgPiBjdXJyZW50SW5SYW5nZSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLy8gLi4vLi4vbm9kZV9tb2R1bGVzLy5wbnBtL3B1cmUtcmFuZEA3LjAuMS9ub2RlX21vZHVsZXMvcHVyZS1yYW5kL2xpYi9lc20vZGlzdHJpYnV0aW9uL1Vuc2FmZVVuaWZvcm1JbnREaXN0cmlidXRpb24uanNcbnZhciBzYWZlTnVtYmVyTWF4U2FmZUludGVnZXIgPSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUjtcbnZhciBzaGFyZWRBID0geyBzaWduOiAxLCBkYXRhOiBbMCwgMF0gfTtcbnZhciBzaGFyZWRCID0geyBzaWduOiAxLCBkYXRhOiBbMCwgMF0gfTtcbnZhciBzaGFyZWRDID0geyBzaWduOiAxLCBkYXRhOiBbMCwgMF0gfTtcbnZhciBzaGFyZWREYXRhID0gWzAsIDBdO1xuZnVuY3Rpb24gdW5pZm9ybUxhcmdlSW50SW50ZXJuYWwoZnJvbSwgdG8sIHJhbmdlU2l6ZSwgcm5nKSB7XG4gIHZhciByYW5nZVNpemVBcnJheUludFZhbHVlID0gcmFuZ2VTaXplIDw9IHNhZmVOdW1iZXJNYXhTYWZlSW50ZWdlciA/IGZyb21OdW1iZXJUb0FycmF5SW50NjQoc2hhcmVkQywgcmFuZ2VTaXplKSA6IHN1YnN0cmFjdEFycmF5SW50NjQoc2hhcmVkQywgZnJvbU51bWJlclRvQXJyYXlJbnQ2NChzaGFyZWRBLCB0byksIGZyb21OdW1iZXJUb0FycmF5SW50NjQoc2hhcmVkQiwgZnJvbSkpO1xuICBpZiAocmFuZ2VTaXplQXJyYXlJbnRWYWx1ZS5kYXRhWzFdID09PSA0Mjk0OTY3Mjk1KSB7XG4gICAgcmFuZ2VTaXplQXJyYXlJbnRWYWx1ZS5kYXRhWzBdICs9IDE7XG4gICAgcmFuZ2VTaXplQXJyYXlJbnRWYWx1ZS5kYXRhWzFdID0gMDtcbiAgfSBlbHNlIHtcbiAgICByYW5nZVNpemVBcnJheUludFZhbHVlLmRhdGFbMV0gKz0gMTtcbiAgfVxuICB1bnNhZmVVbmlmb3JtQXJyYXlJbnREaXN0cmlidXRpb25JbnRlcm5hbChzaGFyZWREYXRhLCByYW5nZVNpemVBcnJheUludFZhbHVlLmRhdGEsIHJuZyk7XG4gIHJldHVybiBzaGFyZWREYXRhWzBdICogNDI5NDk2NzI5NiArIHNoYXJlZERhdGFbMV0gKyBmcm9tO1xufVxuZnVuY3Rpb24gdW5zYWZlVW5pZm9ybUludERpc3RyaWJ1dGlvbihmcm9tLCB0bywgcm5nKSB7XG4gIHZhciByYW5nZVNpemUgPSB0byAtIGZyb207XG4gIGlmIChyYW5nZVNpemUgPD0gNDI5NDk2NzI5NSkge1xuICAgIHZhciBnID0gdW5zYWZlVW5pZm9ybUludERpc3RyaWJ1dGlvbkludGVybmFsKHJhbmdlU2l6ZSArIDEsIHJuZyk7XG4gICAgcmV0dXJuIGcgKyBmcm9tO1xuICB9XG4gIHJldHVybiB1bmlmb3JtTGFyZ2VJbnRJbnRlcm5hbChmcm9tLCB0bywgcmFuZ2VTaXplLCBybmcpO1xufVxuXG4vLyAuLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vcHVyZS1yYW5kQDcuMC4xL25vZGVfbW9kdWxlcy9wdXJlLXJhbmQvbGliL2VzbS9nZW5lcmF0b3IvWG9yb1NoaXJvLmpzXG52YXIgWG9yb1NoaXJvMTI4UGx1cyA9IChmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gWG9yb1NoaXJvMTI4UGx1czIoczAxLCBzMDAsIHMxMSwgczEwKSB7XG4gICAgdGhpcy5zMDEgPSBzMDE7XG4gICAgdGhpcy5zMDAgPSBzMDA7XG4gICAgdGhpcy5zMTEgPSBzMTE7XG4gICAgdGhpcy5zMTAgPSBzMTA7XG4gIH1cbiAgWG9yb1NoaXJvMTI4UGx1czIucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIG5ldyBYb3JvU2hpcm8xMjhQbHVzMih0aGlzLnMwMSwgdGhpcy5zMDAsIHRoaXMuczExLCB0aGlzLnMxMCk7XG4gIH07XG4gIFhvcm9TaGlybzEyOFBsdXMyLnByb3RvdHlwZS5uZXh0ID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIG5leHRSbmcgPSBuZXcgWG9yb1NoaXJvMTI4UGx1czIodGhpcy5zMDEsIHRoaXMuczAwLCB0aGlzLnMxMSwgdGhpcy5zMTApO1xuICAgIHZhciBvdXQgPSBuZXh0Um5nLnVuc2FmZU5leHQoKTtcbiAgICByZXR1cm4gW291dCwgbmV4dFJuZ107XG4gIH07XG4gIFhvcm9TaGlybzEyOFBsdXMyLnByb3RvdHlwZS51bnNhZmVOZXh0ID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIG91dCA9IHRoaXMuczAwICsgdGhpcy5zMTAgfCAwO1xuICAgIHZhciBhMCA9IHRoaXMuczEwIF4gdGhpcy5zMDA7XG4gICAgdmFyIGExID0gdGhpcy5zMTEgXiB0aGlzLnMwMTtcbiAgICB2YXIgczAwID0gdGhpcy5zMDA7XG4gICAgdmFyIHMwMSA9IHRoaXMuczAxO1xuICAgIHRoaXMuczAwID0gczAwIDw8IDI0IF4gczAxID4+PiA4IF4gYTAgXiBhMCA8PCAxNjtcbiAgICB0aGlzLnMwMSA9IHMwMSA8PCAyNCBeIHMwMCA+Pj4gOCBeIGExIF4gKGExIDw8IDE2IHwgYTAgPj4+IDE2KTtcbiAgICB0aGlzLnMxMCA9IGExIDw8IDUgXiBhMCA+Pj4gMjc7XG4gICAgdGhpcy5zMTEgPSBhMCA8PCA1IF4gYTEgPj4+IDI3O1xuICAgIHJldHVybiBvdXQ7XG4gIH07XG4gIFhvcm9TaGlybzEyOFBsdXMyLnByb3RvdHlwZS5qdW1wID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIG5leHRSbmcgPSBuZXcgWG9yb1NoaXJvMTI4UGx1czIodGhpcy5zMDEsIHRoaXMuczAwLCB0aGlzLnMxMSwgdGhpcy5zMTApO1xuICAgIG5leHRSbmcudW5zYWZlSnVtcCgpO1xuICAgIHJldHVybiBuZXh0Um5nO1xuICB9O1xuICBYb3JvU2hpcm8xMjhQbHVzMi5wcm90b3R5cGUudW5zYWZlSnVtcCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBuczAxID0gMDtcbiAgICB2YXIgbnMwMCA9IDA7XG4gICAgdmFyIG5zMTEgPSAwO1xuICAgIHZhciBuczEwID0gMDtcbiAgICB2YXIganVtcCA9IFszNjM5OTU2NjQ1LCAzNzUwNzU3MDEyLCAxMjYxNTY4NTA4LCAzODY0MjYzMzVdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpICE9PSA0OyArK2kpIHtcbiAgICAgIGZvciAodmFyIG1hc2sgPSAxOyBtYXNrOyBtYXNrIDw8PSAxKSB7XG4gICAgICAgIGlmIChqdW1wW2ldICYgbWFzaykge1xuICAgICAgICAgIG5zMDEgXj0gdGhpcy5zMDE7XG4gICAgICAgICAgbnMwMCBePSB0aGlzLnMwMDtcbiAgICAgICAgICBuczExIF49IHRoaXMuczExO1xuICAgICAgICAgIG5zMTAgXj0gdGhpcy5zMTA7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy51bnNhZmVOZXh0KCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuczAxID0gbnMwMTtcbiAgICB0aGlzLnMwMCA9IG5zMDA7XG4gICAgdGhpcy5zMTEgPSBuczExO1xuICAgIHRoaXMuczEwID0gbnMxMDtcbiAgfTtcbiAgWG9yb1NoaXJvMTI4UGx1czIucHJvdG90eXBlLmdldFN0YXRlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIFt0aGlzLnMwMSwgdGhpcy5zMDAsIHRoaXMuczExLCB0aGlzLnMxMF07XG4gIH07XG4gIHJldHVybiBYb3JvU2hpcm8xMjhQbHVzMjtcbn0pKCk7XG5mdW5jdGlvbiBmcm9tU3RhdGUoc3RhdGUpIHtcbiAgdmFyIHZhbGlkID0gc3RhdGUubGVuZ3RoID09PSA0O1xuICBpZiAoIXZhbGlkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlIHN0YXRlIG11c3QgaGF2ZSBiZWVuIHByb2R1Y2VkIGJ5IGEgeG9yb3NoaXJvMTI4cGx1cyBSYW5kb21HZW5lcmF0b3JcIik7XG4gIH1cbiAgcmV0dXJuIG5ldyBYb3JvU2hpcm8xMjhQbHVzKHN0YXRlWzBdLCBzdGF0ZVsxXSwgc3RhdGVbMl0sIHN0YXRlWzNdKTtcbn1cbnZhciB4b3Jvc2hpcm8xMjhwbHVzID0gT2JqZWN0LmFzc2lnbihmdW5jdGlvbihzZWVkKSB7XG4gIHJldHVybiBuZXcgWG9yb1NoaXJvMTI4UGx1cygtMSwgfnNlZWQsIHNlZWQgfCAwLCAwKTtcbn0sIHsgZnJvbVN0YXRlIH0pO1xuXG4vLyBzcmMvc2VydmVyL3JuZy50c1xudmFyIHsgYXNVaW50TiB9ID0gQmlnSW50O1xuZnVuY3Rpb24gcGNnMzIoc3RhdGUpIHtcbiAgY29uc3QgTVVMID0gNjM2NDEzNjIyMzg0Njc5MzAwNW47XG4gIGNvbnN0IElOQyA9IDExNjM0NTgwMDI3NDYyMjYwNzIzbjtcbiAgc3RhdGUgPSBhc1VpbnROKDY0LCBzdGF0ZSAqIE1VTCArIElOQyk7XG4gIGNvbnN0IHhvcnNoaWZ0ZWQgPSBOdW1iZXIoYXNVaW50TigzMiwgKHN0YXRlID4+IDE4biBeIHN0YXRlKSA+PiAyN24pKTtcbiAgY29uc3Qgcm90ID0gTnVtYmVyKGFzVWludE4oMzIsIHN0YXRlID4+IDU5bikpO1xuICByZXR1cm4geG9yc2hpZnRlZCA+PiByb3QgfCB4b3JzaGlmdGVkIDw8IDMyIC0gcm90O1xufVxuZnVuY3Rpb24gZ2VuZXJhdGVGbG9hdDY0KHJuZykge1xuICBjb25zdCBnMSA9IHVuc2FmZVVuaWZvcm1JbnREaXN0cmlidXRpb24oMCwgKDEgPDwgMjYpIC0gMSwgcm5nKTtcbiAgY29uc3QgZzIgPSB1bnNhZmVVbmlmb3JtSW50RGlzdHJpYnV0aW9uKDAsICgxIDw8IDI3KSAtIDEsIHJuZyk7XG4gIGNvbnN0IHZhbHVlID0gKGcxICogTWF0aC5wb3coMiwgMjcpICsgZzIpICogTWF0aC5wb3coMiwgLTUzKTtcbiAgcmV0dXJuIHZhbHVlO1xufVxuZnVuY3Rpb24gbWFrZVJhbmRvbShzZWVkKSB7XG4gIGNvbnN0IHJuZyA9IHhvcm9zaGlybzEyOHBsdXMocGNnMzIoc2VlZC5taWNyb3NTaW5jZVVuaXhFcG9jaCkpO1xuICBjb25zdCByYW5kb20gPSAoKSA9PiBnZW5lcmF0ZUZsb2F0NjQocm5nKTtcbiAgcmFuZG9tLmZpbGwgPSAoYXJyYXkpID0+IHtcbiAgICBjb25zdCBlbGVtID0gYXJyYXkuYXQoMCk7XG4gICAgaWYgKHR5cGVvZiBlbGVtID09PSBcImJpZ2ludFwiKSB7XG4gICAgICBjb25zdCB1cHBlciA9ICgxbiA8PCBCaWdJbnQoYXJyYXkuQllURVNfUEVSX0VMRU1FTlQgKiA4KSkgLSAxbjtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgYXJyYXlbaV0gPSB1bnNhZmVVbmlmb3JtQmlnSW50RGlzdHJpYnV0aW9uKDBuLCB1cHBlciwgcm5nKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBlbGVtID09PSBcIm51bWJlclwiKSB7XG4gICAgICBjb25zdCB1cHBlciA9ICgxIDw8IGFycmF5LkJZVEVTX1BFUl9FTEVNRU5UICogOCkgLSAxO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICBhcnJheVtpXSA9IHVuc2FmZVVuaWZvcm1JbnREaXN0cmlidXRpb24oMCwgdXBwZXIsIHJuZyk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhcnJheTtcbiAgfTtcbiAgcmFuZG9tLnVpbnQzMiA9ICgpID0+IHJuZy51bnNhZmVOZXh0KCk7XG4gIHJhbmRvbS5pbnRlZ2VySW5SYW5nZSA9IChtaW4sIG1heCkgPT4gdW5zYWZlVW5pZm9ybUludERpc3RyaWJ1dGlvbihtaW4sIG1heCwgcm5nKTtcbiAgcmFuZG9tLmJpZ2ludEluUmFuZ2UgPSAobWluLCBtYXgpID0+IHVuc2FmZVVuaWZvcm1CaWdJbnREaXN0cmlidXRpb24obWluLCBtYXgsIHJuZyk7XG4gIHJldHVybiByYW5kb207XG59XG5cbi8vIHNyYy9zZXJ2ZXIvcnVudGltZS50c1xudmFyIHsgZnJlZXplIH0gPSBPYmplY3Q7XG52YXIgc3lzID0gX3N5c2NhbGxzMl8wO1xuZnVuY3Rpb24gcGFyc2VKc29uT2JqZWN0KGpzb24pIHtcbiAgbGV0IHZhbHVlO1xuICB0cnkge1xuICAgIHZhbHVlID0gSlNPTi5wYXJzZShqc29uKTtcbiAgfSBjYXRjaCB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBKU09OOiBmYWlsZWQgdG8gcGFyc2Ugc3RyaW5nXCIpO1xuICB9XG4gIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJFeHBlY3RlZCBhIEpTT04gb2JqZWN0IGF0IHRoZSB0b3AgbGV2ZWxcIik7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxudmFyIEp3dENsYWltc0ltcGwgPSBjbGFzcyB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IEp3dENsYWltcyBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHJhd1BheWxvYWQgVGhlIEpXVCBwYXlsb2FkIGFzIGEgcmF3IEpTT04gc3RyaW5nLlxuICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIGlkZW50aXR5IGZvciB0aGlzIEpXVC4gV2UgYXJlIG9ubHkgdGFraW5nIHRoaXMgYmVjYXVzZSB3ZSBkb24ndCBoYXZlIGEgYmxha2UzIGltcGxlbWVudGF0aW9uICh3aGljaCB3ZSBuZWVkIHRvIGNvbXB1dGUgaXQpLlxuICAgKi9cbiAgY29uc3RydWN0b3IocmF3UGF5bG9hZCwgaWRlbnRpdHkpIHtcbiAgICB0aGlzLnJhd1BheWxvYWQgPSByYXdQYXlsb2FkO1xuICAgIHRoaXMuZnVsbFBheWxvYWQgPSBwYXJzZUpzb25PYmplY3QocmF3UGF5bG9hZCk7XG4gICAgdGhpcy5faWRlbnRpdHkgPSBpZGVudGl0eTtcbiAgfVxuICBmdWxsUGF5bG9hZDtcbiAgX2lkZW50aXR5O1xuICBnZXQgaWRlbnRpdHkoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2lkZW50aXR5O1xuICB9XG4gIGdldCBzdWJqZWN0KCkge1xuICAgIHJldHVybiB0aGlzLmZ1bGxQYXlsb2FkW1wic3ViXCJdO1xuICB9XG4gIGdldCBpc3N1ZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuZnVsbFBheWxvYWRbXCJpc3NcIl07XG4gIH1cbiAgZ2V0IGF1ZGllbmNlKCkge1xuICAgIGNvbnN0IGF1ZCA9IHRoaXMuZnVsbFBheWxvYWRbXCJhdWRcIl07XG4gICAgaWYgKGF1ZCA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIHJldHVybiB0eXBlb2YgYXVkID09PSBcInN0cmluZ1wiID8gW2F1ZF0gOiBhdWQ7XG4gIH1cbn07XG52YXIgQXV0aEN0eEltcGwgPSBjbGFzcyBfQXV0aEN0eEltcGwge1xuICBpc0ludGVybmFsO1xuICAvLyBTb3VyY2Ugb2YgdGhlIEpXVCBwYXlsb2FkIHN0cmluZywgaWYgdGhlcmUgaXMgb25lLlxuICBfand0U291cmNlO1xuICAvLyBXaGV0aGVyIHdlIGhhdmUgaW5pdGlhbGl6ZWQgdGhlIEpXVCBjbGFpbXMuXG4gIF9pbml0aWFsaXplZEpXVCA9IGZhbHNlO1xuICBfand0Q2xhaW1zO1xuICBfc2VuZGVySWRlbnRpdHk7XG4gIGNvbnN0cnVjdG9yKG9wdHMpIHtcbiAgICB0aGlzLmlzSW50ZXJuYWwgPSBvcHRzLmlzSW50ZXJuYWw7XG4gICAgdGhpcy5fand0U291cmNlID0gb3B0cy5qd3RTb3VyY2U7XG4gICAgdGhpcy5fc2VuZGVySWRlbnRpdHkgPSBvcHRzLnNlbmRlcklkZW50aXR5O1xuICB9XG4gIF9pbml0aWFsaXplSldUKCkge1xuICAgIGlmICh0aGlzLl9pbml0aWFsaXplZEpXVCkgcmV0dXJuO1xuICAgIHRoaXMuX2luaXRpYWxpemVkSldUID0gdHJ1ZTtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXMuX2p3dFNvdXJjZSgpO1xuICAgIGlmICghdG9rZW4pIHtcbiAgICAgIHRoaXMuX2p3dENsYWltcyA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2p3dENsYWltcyA9IG5ldyBKd3RDbGFpbXNJbXBsKHRva2VuLCB0aGlzLl9zZW5kZXJJZGVudGl0eSk7XG4gICAgfVxuICAgIE9iamVjdC5mcmVlemUodGhpcyk7XG4gIH1cbiAgLyoqIExhemlseSBjb21wdXRlIHdoZXRoZXIgYSBKV1QgZXhpc3RzIGFuZCBpcyBwYXJzZWFibGUuICovXG4gIGdldCBoYXNKV1QoKSB7XG4gICAgdGhpcy5faW5pdGlhbGl6ZUpXVCgpO1xuICAgIHJldHVybiB0aGlzLl9qd3RDbGFpbXMgIT09IG51bGw7XG4gIH1cbiAgLyoqIExhemlseSBwYXJzZSB0aGUgSnd0Q2xhaW1zIG9ubHkgd2hlbiBhY2Nlc3NlZC4gKi9cbiAgZ2V0IGp3dCgpIHtcbiAgICB0aGlzLl9pbml0aWFsaXplSldUKCk7XG4gICAgcmV0dXJuIHRoaXMuX2p3dENsYWltcztcbiAgfVxuICAvKiogQ3JlYXRlIGEgY29udGV4dCByZXByZXNlbnRpbmcgaW50ZXJuYWwgKG5vbi11c2VyKSByZXF1ZXN0cy4gKi9cbiAgc3RhdGljIGludGVybmFsKCkge1xuICAgIHJldHVybiBuZXcgX0F1dGhDdHhJbXBsKHtcbiAgICAgIGlzSW50ZXJuYWw6IHRydWUsXG4gICAgICBqd3RTb3VyY2U6ICgpID0+IG51bGwsXG4gICAgICBzZW5kZXJJZGVudGl0eTogSWRlbnRpdHkuemVybygpXG4gICAgfSk7XG4gIH1cbiAgLyoqIElmIHRoZXJlIGlzIGEgY29ubmVjdGlvbiBpZCwgbG9vayB1cCB0aGUgSldUIHBheWxvYWQgZnJvbSB0aGUgc3lzdGVtIHRhYmxlcy4gKi9cbiAgc3RhdGljIGZyb21TeXN0ZW1UYWJsZXMoY29ubmVjdGlvbklkLCBzZW5kZXIpIHtcbiAgICBpZiAoY29ubmVjdGlvbklkID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gbmV3IF9BdXRoQ3R4SW1wbCh7XG4gICAgICAgIGlzSW50ZXJuYWw6IGZhbHNlLFxuICAgICAgICBqd3RTb3VyY2U6ICgpID0+IG51bGwsXG4gICAgICAgIHNlbmRlcklkZW50aXR5OiBzZW5kZXJcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IF9BdXRoQ3R4SW1wbCh7XG4gICAgICBpc0ludGVybmFsOiBmYWxzZSxcbiAgICAgIGp3dFNvdXJjZTogKCkgPT4ge1xuICAgICAgICBjb25zdCBwYXlsb2FkQnVmID0gc3lzLmdldF9qd3RfcGF5bG9hZChjb25uZWN0aW9uSWQuX19jb25uZWN0aW9uX2lkX18pO1xuICAgICAgICBpZiAocGF5bG9hZEJ1Zi5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuICAgICAgICBjb25zdCBwYXlsb2FkU3RyID0gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKHBheWxvYWRCdWYpO1xuICAgICAgICByZXR1cm4gcGF5bG9hZFN0cjtcbiAgICAgIH0sXG4gICAgICBzZW5kZXJJZGVudGl0eTogc2VuZGVyXG4gICAgfSk7XG4gIH1cbn07XG52YXIgUmVkdWNlckN0eEltcGwgPSBjbGFzcyBSZWR1Y2VyQ3R4IHtcbiAgI2lkZW50aXR5O1xuICAjc2VuZGVyQXV0aDtcbiAgI3V1aWRDb3VudGVyO1xuICAjcmFuZG9tO1xuICBzZW5kZXI7XG4gIHRpbWVzdGFtcDtcbiAgY29ubmVjdGlvbklkO1xuICBkYjtcbiAgY29uc3RydWN0b3Ioc2VuZGVyLCB0aW1lc3RhbXAsIGNvbm5lY3Rpb25JZCwgZGJWaWV3KSB7XG4gICAgT2JqZWN0LnNlYWwodGhpcyk7XG4gICAgdGhpcy5zZW5kZXIgPSBzZW5kZXI7XG4gICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7XG4gICAgdGhpcy5jb25uZWN0aW9uSWQgPSBjb25uZWN0aW9uSWQ7XG4gICAgdGhpcy5kYiA9IGRiVmlldztcbiAgfVxuICAvKiogUmVzZXQgdGhlIGBSZWR1Y2VyQ3R4YCB0byBiZSB1c2VkIGZvciBhIG5ldyB0cmFuc2FjdGlvbiAqL1xuICBzdGF0aWMgcmVzZXQobWUsIHNlbmRlciwgdGltZXN0YW1wLCBjb25uZWN0aW9uSWQpIHtcbiAgICBtZS5zZW5kZXIgPSBzZW5kZXI7XG4gICAgbWUudGltZXN0YW1wID0gdGltZXN0YW1wO1xuICAgIG1lLmNvbm5lY3Rpb25JZCA9IGNvbm5lY3Rpb25JZDtcbiAgICBtZS4jdXVpZENvdW50ZXIgPSB2b2lkIDA7XG4gICAgbWUuI3NlbmRlckF1dGggPSB2b2lkIDA7XG4gIH1cbiAgZ2V0IGlkZW50aXR5KCkge1xuICAgIHJldHVybiB0aGlzLiNpZGVudGl0eSA/Pz0gbmV3IElkZW50aXR5KHN5cy5pZGVudGl0eSgpKTtcbiAgfVxuICBnZXQgc2VuZGVyQXV0aCgpIHtcbiAgICByZXR1cm4gdGhpcy4jc2VuZGVyQXV0aCA/Pz0gQXV0aEN0eEltcGwuZnJvbVN5c3RlbVRhYmxlcyhcbiAgICAgIHRoaXMuY29ubmVjdGlvbklkLFxuICAgICAgdGhpcy5zZW5kZXJcbiAgICApO1xuICB9XG4gIGdldCByYW5kb20oKSB7XG4gICAgcmV0dXJuIHRoaXMuI3JhbmRvbSA/Pz0gbWFrZVJhbmRvbSh0aGlzLnRpbWVzdGFtcCk7XG4gIH1cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyByYW5kb20ge0BsaW5rIFV1aWR9IGB2NGAgdXNpbmcgdGhpcyBgUmVkdWNlckN0eGAncyBSTkcuXG4gICAqL1xuICBuZXdVdWlkVjQoKSB7XG4gICAgY29uc3QgYnl0ZXMgPSB0aGlzLnJhbmRvbS5maWxsKG5ldyBVaW50OEFycmF5KDE2KSk7XG4gICAgcmV0dXJuIFV1aWQuZnJvbVJhbmRvbUJ5dGVzVjQoYnl0ZXMpO1xuICB9XG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgc29ydGFibGUge0BsaW5rIFV1aWR9IGB2N2AgdXNpbmcgdGhpcyBgUmVkdWNlckN0eGAncyBSTkcsIGNvdW50ZXIsXG4gICAqIGFuZCB0aW1lc3RhbXAuXG4gICAqL1xuICBuZXdVdWlkVjcoKSB7XG4gICAgY29uc3QgYnl0ZXMgPSB0aGlzLnJhbmRvbS5maWxsKG5ldyBVaW50OEFycmF5KDQpKTtcbiAgICBjb25zdCBjb3VudGVyID0gdGhpcy4jdXVpZENvdW50ZXIgPz89IHsgdmFsdWU6IDAgfTtcbiAgICByZXR1cm4gVXVpZC5mcm9tQ291bnRlclY3KGNvdW50ZXIsIHRoaXMudGltZXN0YW1wLCBieXRlcyk7XG4gIH1cbn07XG52YXIgY2FsbFVzZXJGdW5jdGlvbiA9IGZ1bmN0aW9uIF9fc3BhY2V0aW1lZGJfZW5kX3Nob3J0X2JhY2t0cmFjZShmbiwgLi4uYXJncykge1xuICByZXR1cm4gZm4oLi4uYXJncyk7XG59O1xudmFyIG1ha2VIb29rcyA9IChzY2hlbWEyKSA9PiBuZXcgTW9kdWxlSG9va3NJbXBsKHNjaGVtYTIpO1xudmFyIE1vZHVsZUhvb2tzSW1wbCA9IGNsYXNzIHtcbiAgI3NjaGVtYTtcbiAgI2RiVmlld187XG4gICNyZWR1Y2VyQXJnc0Rlc2VyaWFsaXplcnM7XG4gIC8qKiBDYWNoZSB0aGUgYFJlZHVjZXJDdHhgIG9iamVjdCB0byBhdm9pZCBhbGxvY2F0aW5nIGFuZXcgZm9yIGV2ZXIgcmVkdWNlciBjYWxsLiAqL1xuICAjcmVkdWNlckN0eF87XG4gIGNvbnN0cnVjdG9yKHNjaGVtYTIpIHtcbiAgICB0aGlzLiNzY2hlbWEgPSBzY2hlbWEyO1xuICAgIHRoaXMuI3JlZHVjZXJBcmdzRGVzZXJpYWxpemVycyA9IHNjaGVtYTIubW9kdWxlRGVmLnJlZHVjZXJzLm1hcChcbiAgICAgICh7IHBhcmFtcyB9KSA9PiBQcm9kdWN0VHlwZS5tYWtlRGVzZXJpYWxpemVyKHBhcmFtcywgc2NoZW1hMi50eXBlc3BhY2UpXG4gICAgKTtcbiAgfVxuICBnZXQgI2RiVmlldygpIHtcbiAgICByZXR1cm4gdGhpcy4jZGJWaWV3XyA/Pz0gZnJlZXplKFxuICAgICAgT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICBPYmplY3QudmFsdWVzKHRoaXMuI3NjaGVtYS5zY2hlbWFUeXBlLnRhYmxlcykubWFwKCh0YWJsZTIpID0+IFtcbiAgICAgICAgICB0YWJsZTIuYWNjZXNzb3JOYW1lLFxuICAgICAgICAgIG1ha2VUYWJsZVZpZXcodGhpcy4jc2NoZW1hLnR5cGVzcGFjZSwgdGFibGUyLnRhYmxlRGVmKVxuICAgICAgICBdKVxuICAgICAgKVxuICAgICk7XG4gIH1cbiAgZ2V0ICNyZWR1Y2VyQ3R4KCkge1xuICAgIHJldHVybiB0aGlzLiNyZWR1Y2VyQ3R4XyA/Pz0gbmV3IFJlZHVjZXJDdHhJbXBsKFxuICAgICAgSWRlbnRpdHkuemVybygpLFxuICAgICAgVGltZXN0YW1wLlVOSVhfRVBPQ0gsXG4gICAgICBudWxsLFxuICAgICAgdGhpcy4jZGJWaWV3XG4gICAgKTtcbiAgfVxuICBfX2Rlc2NyaWJlX21vZHVsZV9fKCkge1xuICAgIGNvbnN0IHdyaXRlciA9IG5ldyBCaW5hcnlXcml0ZXIoMTI4KTtcbiAgICBSYXdNb2R1bGVEZWYuc2VyaWFsaXplKFxuICAgICAgd3JpdGVyLFxuICAgICAgUmF3TW9kdWxlRGVmLlYxMCh0aGlzLiNzY2hlbWEucmF3TW9kdWxlRGVmVjEwKCkpXG4gICAgKTtcbiAgICByZXR1cm4gd3JpdGVyLmdldEJ1ZmZlcigpO1xuICB9XG4gIF9fZ2V0X2Vycm9yX2NvbnN0cnVjdG9yX18oY29kZSkge1xuICAgIHJldHVybiBnZXRFcnJvckNvbnN0cnVjdG9yKGNvZGUpO1xuICB9XG4gIGdldCBfX3NlbmRlcl9lcnJvcl9jbGFzc19fKCkge1xuICAgIHJldHVybiBTZW5kZXJFcnJvcjtcbiAgfVxuICBfX2NhbGxfcmVkdWNlcl9fKHJlZHVjZXJJZCwgc2VuZGVyLCBjb25uSWQsIHRpbWVzdGFtcCwgYXJnc0J1Zikge1xuICAgIGNvbnN0IG1vZHVsZUN0eCA9IHRoaXMuI3NjaGVtYTtcbiAgICBjb25zdCBkZXNlcmlhbGl6ZUFyZ3MgPSB0aGlzLiNyZWR1Y2VyQXJnc0Rlc2VyaWFsaXplcnNbcmVkdWNlcklkXTtcbiAgICBCSU5BUllfUkVBREVSLnJlc2V0KGFyZ3NCdWYpO1xuICAgIGNvbnN0IGFyZ3MgPSBkZXNlcmlhbGl6ZUFyZ3MoQklOQVJZX1JFQURFUik7XG4gICAgY29uc3Qgc2VuZGVySWRlbnRpdHkgPSBuZXcgSWRlbnRpdHkoc2VuZGVyKTtcbiAgICBjb25zdCBjdHggPSB0aGlzLiNyZWR1Y2VyQ3R4O1xuICAgIFJlZHVjZXJDdHhJbXBsLnJlc2V0KFxuICAgICAgY3R4LFxuICAgICAgc2VuZGVySWRlbnRpdHksXG4gICAgICBuZXcgVGltZXN0YW1wKHRpbWVzdGFtcCksXG4gICAgICBDb25uZWN0aW9uSWQubnVsbElmWmVybyhuZXcgQ29ubmVjdGlvbklkKGNvbm5JZCkpXG4gICAgKTtcbiAgICBjYWxsVXNlckZ1bmN0aW9uKG1vZHVsZUN0eC5yZWR1Y2Vyc1tyZWR1Y2VySWRdLCBjdHgsIGFyZ3MpO1xuICB9XG4gIF9fY2FsbF92aWV3X18oaWQsIHNlbmRlciwgYXJnc0J1Zikge1xuICAgIGNvbnN0IG1vZHVsZUN0eCA9IHRoaXMuI3NjaGVtYTtcbiAgICBjb25zdCB7IGZuLCBkZXNlcmlhbGl6ZVBhcmFtcywgc2VyaWFsaXplUmV0dXJuLCByZXR1cm5UeXBlQmFzZVNpemUgfSA9IG1vZHVsZUN0eC52aWV3c1tpZF07XG4gICAgY29uc3QgY3R4ID0gZnJlZXplKHtcbiAgICAgIHNlbmRlcjogbmV3IElkZW50aXR5KHNlbmRlciksXG4gICAgICAvLyB0aGlzIGlzIHRoZSBub24tcmVhZG9ubHkgRGJWaWV3LCBidXQgdGhlIHR5cGluZyBmb3IgdGhlIHVzZXIgd2lsbCBiZVxuICAgICAgLy8gdGhlIHJlYWRvbmx5IG9uZSwgYW5kIGlmIHRoZXkgZG8gY2FsbCBtdXRhdGluZyBmdW5jdGlvbnMgaXQgd2lsbCBmYWlsXG4gICAgICAvLyBhdCBydW50aW1lXG4gICAgICBkYjogdGhpcy4jZGJWaWV3LFxuICAgICAgZnJvbTogbWFrZVF1ZXJ5QnVpbGRlcihtb2R1bGVDdHguc2NoZW1hVHlwZSlcbiAgICB9KTtcbiAgICBjb25zdCBhcmdzID0gZGVzZXJpYWxpemVQYXJhbXMobmV3IEJpbmFyeVJlYWRlcihhcmdzQnVmKSk7XG4gICAgY29uc3QgcmV0ID0gY2FsbFVzZXJGdW5jdGlvbihmbiwgY3R4LCBhcmdzKTtcbiAgICBjb25zdCByZXRCdWYgPSBuZXcgQmluYXJ5V3JpdGVyKHJldHVyblR5cGVCYXNlU2l6ZSk7XG4gICAgaWYgKGlzUm93VHlwZWRRdWVyeShyZXQpKSB7XG4gICAgICBjb25zdCBxdWVyeSA9IHRvU3FsKHJldCk7XG4gICAgICBWaWV3UmVzdWx0SGVhZGVyLnNlcmlhbGl6ZShyZXRCdWYsIFZpZXdSZXN1bHRIZWFkZXIuUmF3U3FsKHF1ZXJ5KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIFZpZXdSZXN1bHRIZWFkZXIuc2VyaWFsaXplKHJldEJ1ZiwgVmlld1Jlc3VsdEhlYWRlci5Sb3dEYXRhKTtcbiAgICAgIHNlcmlhbGl6ZVJldHVybihyZXRCdWYsIHJldCk7XG4gICAgfVxuICAgIHJldHVybiB7IGRhdGE6IHJldEJ1Zi5nZXRCdWZmZXIoKSB9O1xuICB9XG4gIF9fY2FsbF92aWV3X2Fub25fXyhpZCwgYXJnc0J1Zikge1xuICAgIGNvbnN0IG1vZHVsZUN0eCA9IHRoaXMuI3NjaGVtYTtcbiAgICBjb25zdCB7IGZuLCBkZXNlcmlhbGl6ZVBhcmFtcywgc2VyaWFsaXplUmV0dXJuLCByZXR1cm5UeXBlQmFzZVNpemUgfSA9IG1vZHVsZUN0eC5hbm9uVmlld3NbaWRdO1xuICAgIGNvbnN0IGN0eCA9IGZyZWV6ZSh7XG4gICAgICAvLyB0aGlzIGlzIHRoZSBub24tcmVhZG9ubHkgRGJWaWV3LCBidXQgdGhlIHR5cGluZyBmb3IgdGhlIHVzZXIgd2lsbCBiZVxuICAgICAgLy8gdGhlIHJlYWRvbmx5IG9uZSwgYW5kIGlmIHRoZXkgZG8gY2FsbCBtdXRhdGluZyBmdW5jdGlvbnMgaXQgd2lsbCBmYWlsXG4gICAgICAvLyBhdCBydW50aW1lXG4gICAgICBkYjogdGhpcy4jZGJWaWV3LFxuICAgICAgZnJvbTogbWFrZVF1ZXJ5QnVpbGRlcihtb2R1bGVDdHguc2NoZW1hVHlwZSlcbiAgICB9KTtcbiAgICBjb25zdCBhcmdzID0gZGVzZXJpYWxpemVQYXJhbXMobmV3IEJpbmFyeVJlYWRlcihhcmdzQnVmKSk7XG4gICAgY29uc3QgcmV0ID0gY2FsbFVzZXJGdW5jdGlvbihmbiwgY3R4LCBhcmdzKTtcbiAgICBjb25zdCByZXRCdWYgPSBuZXcgQmluYXJ5V3JpdGVyKHJldHVyblR5cGVCYXNlU2l6ZSk7XG4gICAgaWYgKGlzUm93VHlwZWRRdWVyeShyZXQpKSB7XG4gICAgICBjb25zdCBxdWVyeSA9IHRvU3FsKHJldCk7XG4gICAgICBWaWV3UmVzdWx0SGVhZGVyLnNlcmlhbGl6ZShyZXRCdWYsIFZpZXdSZXN1bHRIZWFkZXIuUmF3U3FsKHF1ZXJ5KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIFZpZXdSZXN1bHRIZWFkZXIuc2VyaWFsaXplKHJldEJ1ZiwgVmlld1Jlc3VsdEhlYWRlci5Sb3dEYXRhKTtcbiAgICAgIHNlcmlhbGl6ZVJldHVybihyZXRCdWYsIHJldCk7XG4gICAgfVxuICAgIHJldHVybiB7IGRhdGE6IHJldEJ1Zi5nZXRCdWZmZXIoKSB9O1xuICB9XG4gIF9fY2FsbF9wcm9jZWR1cmVfXyhpZCwgc2VuZGVyLCBjb25uZWN0aW9uX2lkLCB0aW1lc3RhbXAsIGFyZ3MpIHtcbiAgICByZXR1cm4gY2FsbFByb2NlZHVyZShcbiAgICAgIHRoaXMuI3NjaGVtYSxcbiAgICAgIGlkLFxuICAgICAgbmV3IElkZW50aXR5KHNlbmRlciksXG4gICAgICBDb25uZWN0aW9uSWQubnVsbElmWmVybyhuZXcgQ29ubmVjdGlvbklkKGNvbm5lY3Rpb25faWQpKSxcbiAgICAgIG5ldyBUaW1lc3RhbXAodGltZXN0YW1wKSxcbiAgICAgIGFyZ3MsXG4gICAgICAoKSA9PiB0aGlzLiNkYlZpZXdcbiAgICApO1xuICB9XG59O1xudmFyIEJJTkFSWV9XUklURVIgPSBuZXcgQmluYXJ5V3JpdGVyKDApO1xudmFyIEJJTkFSWV9SRUFERVIgPSBuZXcgQmluYXJ5UmVhZGVyKG5ldyBVaW50OEFycmF5KCkpO1xuZnVuY3Rpb24gbWFrZVRhYmxlVmlldyh0eXBlc3BhY2UsIHRhYmxlMikge1xuICBjb25zdCB0YWJsZV9pZCA9IHN5cy50YWJsZV9pZF9mcm9tX25hbWUodGFibGUyLnNvdXJjZU5hbWUpO1xuICBjb25zdCByb3dUeXBlID0gdHlwZXNwYWNlLnR5cGVzW3RhYmxlMi5wcm9kdWN0VHlwZVJlZl07XG4gIGlmIChyb3dUeXBlLnRhZyAhPT0gXCJQcm9kdWN0XCIpIHtcbiAgICB0aHJvdyBcImltcG9zc2libGVcIjtcbiAgfVxuICBjb25zdCBzZXJpYWxpemVSb3cgPSBBbGdlYnJhaWNUeXBlLm1ha2VTZXJpYWxpemVyKHJvd1R5cGUsIHR5cGVzcGFjZSk7XG4gIGNvbnN0IGRlc2VyaWFsaXplUm93ID0gQWxnZWJyYWljVHlwZS5tYWtlRGVzZXJpYWxpemVyKHJvd1R5cGUsIHR5cGVzcGFjZSk7XG4gIGNvbnN0IHNlcXVlbmNlcyA9IHRhYmxlMi5zZXF1ZW5jZXMubWFwKChzZXEpID0+IHtcbiAgICBjb25zdCBjb2wgPSByb3dUeXBlLnZhbHVlLmVsZW1lbnRzW3NlcS5jb2x1bW5dO1xuICAgIGNvbnN0IGNvbFR5cGUgPSBjb2wuYWxnZWJyYWljVHlwZTtcbiAgICBsZXQgc2VxdWVuY2VUcmlnZ2VyO1xuICAgIHN3aXRjaCAoY29sVHlwZS50YWcpIHtcbiAgICAgIGNhc2UgXCJVOFwiOlxuICAgICAgY2FzZSBcIkk4XCI6XG4gICAgICBjYXNlIFwiVTE2XCI6XG4gICAgICBjYXNlIFwiSTE2XCI6XG4gICAgICBjYXNlIFwiVTMyXCI6XG4gICAgICBjYXNlIFwiSTMyXCI6XG4gICAgICAgIHNlcXVlbmNlVHJpZ2dlciA9IDA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcIlU2NFwiOlxuICAgICAgY2FzZSBcIkk2NFwiOlxuICAgICAgY2FzZSBcIlUxMjhcIjpcbiAgICAgIGNhc2UgXCJJMTI4XCI6XG4gICAgICBjYXNlIFwiVTI1NlwiOlxuICAgICAgY2FzZSBcIkkyNTZcIjpcbiAgICAgICAgc2VxdWVuY2VUcmlnZ2VyID0gMG47XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcImludmFsaWQgc2VxdWVuY2UgdHlwZVwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbE5hbWU6IGNvbC5uYW1lLFxuICAgICAgc2VxdWVuY2VUcmlnZ2VyLFxuICAgICAgZGVzZXJpYWxpemU6IEFsZ2VicmFpY1R5cGUubWFrZURlc2VyaWFsaXplcihjb2xUeXBlLCB0eXBlc3BhY2UpXG4gICAgfTtcbiAgfSk7XG4gIGNvbnN0IGhhc0F1dG9JbmNyZW1lbnQgPSBzZXF1ZW5jZXMubGVuZ3RoID4gMDtcbiAgY29uc3QgaXRlciA9ICgpID0+IHRhYmxlSXRlcmF0b3Ioc3lzLmRhdGFzdG9yZV90YWJsZV9zY2FuX2JzYXRuKHRhYmxlX2lkKSwgZGVzZXJpYWxpemVSb3cpO1xuICBjb25zdCBpbnRlZ3JhdGVHZW5lcmF0ZWRDb2x1bW5zID0gaGFzQXV0b0luY3JlbWVudCA/IChyb3csIHJldF9idWYpID0+IHtcbiAgICBCSU5BUllfUkVBREVSLnJlc2V0KHJldF9idWYpO1xuICAgIGZvciAoY29uc3QgeyBjb2xOYW1lLCBkZXNlcmlhbGl6ZSwgc2VxdWVuY2VUcmlnZ2VyIH0gb2Ygc2VxdWVuY2VzKSB7XG4gICAgICBpZiAocm93W2NvbE5hbWVdID09PSBzZXF1ZW5jZVRyaWdnZXIpIHtcbiAgICAgICAgcm93W2NvbE5hbWVdID0gZGVzZXJpYWxpemUoQklOQVJZX1JFQURFUik7XG4gICAgICB9XG4gICAgfVxuICB9IDogbnVsbDtcbiAgY29uc3QgdGFibGVNZXRob2RzID0ge1xuICAgIGNvdW50OiAoKSA9PiBzeXMuZGF0YXN0b3JlX3RhYmxlX3Jvd19jb3VudCh0YWJsZV9pZCksXG4gICAgaXRlcixcbiAgICBbU3ltYm9sLml0ZXJhdG9yXTogKCkgPT4gaXRlcigpLFxuICAgIGluc2VydDogKHJvdykgPT4ge1xuICAgICAgY29uc3QgYnVmID0gTEVBRl9CVUY7XG4gICAgICBCSU5BUllfV1JJVEVSLnJlc2V0KGJ1Zik7XG4gICAgICBzZXJpYWxpemVSb3coQklOQVJZX1dSSVRFUiwgcm93KTtcbiAgICAgIHN5cy5kYXRhc3RvcmVfaW5zZXJ0X2JzYXRuKHRhYmxlX2lkLCBidWYuYnVmZmVyLCBCSU5BUllfV1JJVEVSLm9mZnNldCk7XG4gICAgICBjb25zdCByZXQgPSB7IC4uLnJvdyB9O1xuICAgICAgaW50ZWdyYXRlR2VuZXJhdGVkQ29sdW1ucz8uKHJldCwgYnVmLnZpZXcpO1xuICAgICAgcmV0dXJuIHJldDtcbiAgICB9LFxuICAgIGRlbGV0ZTogKHJvdykgPT4ge1xuICAgICAgY29uc3QgYnVmID0gTEVBRl9CVUY7XG4gICAgICBCSU5BUllfV1JJVEVSLnJlc2V0KGJ1Zik7XG4gICAgICBCSU5BUllfV1JJVEVSLndyaXRlVTMyKDEpO1xuICAgICAgc2VyaWFsaXplUm93KEJJTkFSWV9XUklURVIsIHJvdyk7XG4gICAgICBjb25zdCBjb3VudCA9IHN5cy5kYXRhc3RvcmVfZGVsZXRlX2FsbF9ieV9lcV9ic2F0bihcbiAgICAgICAgdGFibGVfaWQsXG4gICAgICAgIGJ1Zi5idWZmZXIsXG4gICAgICAgIEJJTkFSWV9XUklURVIub2Zmc2V0XG4gICAgICApO1xuICAgICAgcmV0dXJuIGNvdW50ID4gMDtcbiAgICB9XG4gIH07XG4gIGNvbnN0IHRhYmxlVmlldyA9IE9iamVjdC5hc3NpZ24oXG4gICAgLyogQF9fUFVSRV9fICovIE9iamVjdC5jcmVhdGUobnVsbCksXG4gICAgdGFibGVNZXRob2RzXG4gICk7XG4gIGZvciAoY29uc3QgaW5kZXhEZWYgb2YgdGFibGUyLmluZGV4ZXMpIHtcbiAgICBjb25zdCBhY2Nlc3Nvck5hbWUgPSBpbmRleERlZi5hY2Nlc3Nvck5hbWU7XG4gICAgY29uc3QgaW5kZXhfaWQgPSBzeXMuaW5kZXhfaWRfZnJvbV9uYW1lKGluZGV4RGVmLnNvdXJjZU5hbWUpO1xuICAgIGxldCBjb2x1bW5faWRzO1xuICAgIGxldCBpc0hhc2hJbmRleCA9IGZhbHNlO1xuICAgIHN3aXRjaCAoaW5kZXhEZWYuYWxnb3JpdGhtLnRhZykge1xuICAgICAgY2FzZSBcIkhhc2hcIjpcbiAgICAgICAgaXNIYXNoSW5kZXggPSB0cnVlO1xuICAgICAgICBjb2x1bW5faWRzID0gaW5kZXhEZWYuYWxnb3JpdGhtLnZhbHVlO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJCVHJlZVwiOlxuICAgICAgICBjb2x1bW5faWRzID0gaW5kZXhEZWYuYWxnb3JpdGhtLnZhbHVlO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgXCJEaXJlY3RcIjpcbiAgICAgICAgY29sdW1uX2lkcyA9IFtpbmRleERlZi5hbGdvcml0aG0udmFsdWVdO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgY29uc3QgbnVtQ29sdW1ucyA9IGNvbHVtbl9pZHMubGVuZ3RoO1xuICAgIGNvbnN0IGNvbHVtblNldCA9IG5ldyBTZXQoY29sdW1uX2lkcyk7XG4gICAgY29uc3QgaXNVbmlxdWUgPSB0YWJsZTIuY29uc3RyYWludHMuZmlsdGVyKCh4KSA9PiB4LmRhdGEudGFnID09PSBcIlVuaXF1ZVwiKS5zb21lKCh4KSA9PiBjb2x1bW5TZXQuaXNTdWJzZXRPZihuZXcgU2V0KHguZGF0YS52YWx1ZS5jb2x1bW5zKSkpO1xuICAgIGNvbnN0IGlzUHJpbWFyeUtleSA9IGlzVW5pcXVlICYmIGNvbHVtbl9pZHMubGVuZ3RoID09PSB0YWJsZTIucHJpbWFyeUtleS5sZW5ndGggJiYgY29sdW1uX2lkcy5ldmVyeSgoaWQsIGkpID0+IHRhYmxlMi5wcmltYXJ5S2V5W2ldID09PSBpZCk7XG4gICAgY29uc3QgaW5kZXhTZXJpYWxpemVycyA9IGNvbHVtbl9pZHMubWFwKFxuICAgICAgKGlkKSA9PiBBbGdlYnJhaWNUeXBlLm1ha2VTZXJpYWxpemVyKFxuICAgICAgICByb3dUeXBlLnZhbHVlLmVsZW1lbnRzW2lkXS5hbGdlYnJhaWNUeXBlLFxuICAgICAgICB0eXBlc3BhY2VcbiAgICAgIClcbiAgICApO1xuICAgIGNvbnN0IHNlcmlhbGl6ZVBvaW50ID0gKGJ1ZmZlciwgY29sVmFsKSA9PiB7XG4gICAgICBCSU5BUllfV1JJVEVSLnJlc2V0KGJ1ZmZlcik7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bUNvbHVtbnM7IGkrKykge1xuICAgICAgICBpbmRleFNlcmlhbGl6ZXJzW2ldKEJJTkFSWV9XUklURVIsIGNvbFZhbFtpXSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gQklOQVJZX1dSSVRFUi5vZmZzZXQ7XG4gICAgfTtcbiAgICBjb25zdCBzZXJpYWxpemVTaW5nbGVFbGVtZW50ID0gbnVtQ29sdW1ucyA9PT0gMSA/IGluZGV4U2VyaWFsaXplcnNbMF0gOiBudWxsO1xuICAgIGNvbnN0IHNlcmlhbGl6ZVNpbmdsZVBvaW50ID0gc2VyaWFsaXplU2luZ2xlRWxlbWVudCAmJiAoKGJ1ZmZlciwgY29sVmFsKSA9PiB7XG4gICAgICBCSU5BUllfV1JJVEVSLnJlc2V0KGJ1ZmZlcik7XG4gICAgICBzZXJpYWxpemVTaW5nbGVFbGVtZW50KEJJTkFSWV9XUklURVIsIGNvbFZhbCk7XG4gICAgICByZXR1cm4gQklOQVJZX1dSSVRFUi5vZmZzZXQ7XG4gICAgfSk7XG4gICAgbGV0IGluZGV4O1xuICAgIGlmIChpc1VuaXF1ZSAmJiBzZXJpYWxpemVTaW5nbGVQb2ludCkge1xuICAgICAgY29uc3QgYmFzZSA9IHtcbiAgICAgICAgZmluZDogKGNvbFZhbCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGJ1ZiA9IExFQUZfQlVGO1xuICAgICAgICAgIGNvbnN0IHBvaW50X2xlbiA9IHNlcmlhbGl6ZVNpbmdsZVBvaW50KGJ1ZiwgY29sVmFsKTtcbiAgICAgICAgICBjb25zdCBpdGVyX2lkID0gc3lzLmRhdGFzdG9yZV9pbmRleF9zY2FuX3BvaW50X2JzYXRuKFxuICAgICAgICAgICAgaW5kZXhfaWQsXG4gICAgICAgICAgICBidWYuYnVmZmVyLFxuICAgICAgICAgICAgcG9pbnRfbGVuXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gdGFibGVJdGVyYXRlT25lKGl0ZXJfaWQsIGRlc2VyaWFsaXplUm93KTtcbiAgICAgICAgfSxcbiAgICAgICAgZGVsZXRlOiAoY29sVmFsKSA9PiB7XG4gICAgICAgICAgY29uc3QgYnVmID0gTEVBRl9CVUY7XG4gICAgICAgICAgY29uc3QgcG9pbnRfbGVuID0gc2VyaWFsaXplU2luZ2xlUG9pbnQoYnVmLCBjb2xWYWwpO1xuICAgICAgICAgIGNvbnN0IG51bSA9IHN5cy5kYXRhc3RvcmVfZGVsZXRlX2J5X2luZGV4X3NjYW5fcG9pbnRfYnNhdG4oXG4gICAgICAgICAgICBpbmRleF9pZCxcbiAgICAgICAgICAgIGJ1Zi5idWZmZXIsXG4gICAgICAgICAgICBwb2ludF9sZW5cbiAgICAgICAgICApO1xuICAgICAgICAgIHJldHVybiBudW0gPiAwO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgaWYgKGlzUHJpbWFyeUtleSkge1xuICAgICAgICBiYXNlLnVwZGF0ZSA9IChyb3cpID0+IHtcbiAgICAgICAgICBjb25zdCBidWYgPSBMRUFGX0JVRjtcbiAgICAgICAgICBCSU5BUllfV1JJVEVSLnJlc2V0KGJ1Zik7XG4gICAgICAgICAgc2VyaWFsaXplUm93KEJJTkFSWV9XUklURVIsIHJvdyk7XG4gICAgICAgICAgc3lzLmRhdGFzdG9yZV91cGRhdGVfYnNhdG4oXG4gICAgICAgICAgICB0YWJsZV9pZCxcbiAgICAgICAgICAgIGluZGV4X2lkLFxuICAgICAgICAgICAgYnVmLmJ1ZmZlcixcbiAgICAgICAgICAgIEJJTkFSWV9XUklURVIub2Zmc2V0XG4gICAgICAgICAgKTtcbiAgICAgICAgICBpbnRlZ3JhdGVHZW5lcmF0ZWRDb2x1bW5zPy4ocm93LCBidWYudmlldyk7XG4gICAgICAgICAgcmV0dXJuIHJvdztcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGluZGV4ID0gYmFzZTtcbiAgICB9IGVsc2UgaWYgKGlzVW5pcXVlKSB7XG4gICAgICBjb25zdCBiYXNlID0ge1xuICAgICAgICBmaW5kOiAoY29sVmFsKSA9PiB7XG4gICAgICAgICAgaWYgKGNvbFZhbC5sZW5ndGggIT09IG51bUNvbHVtbnMpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXCJ3cm9uZyBudW1iZXIgb2YgZWxlbWVudHNcIik7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGJ1ZiA9IExFQUZfQlVGO1xuICAgICAgICAgIGNvbnN0IHBvaW50X2xlbiA9IHNlcmlhbGl6ZVBvaW50KGJ1ZiwgY29sVmFsKTtcbiAgICAgICAgICBjb25zdCBpdGVyX2lkID0gc3lzLmRhdGFzdG9yZV9pbmRleF9zY2FuX3BvaW50X2JzYXRuKFxuICAgICAgICAgICAgaW5kZXhfaWQsXG4gICAgICAgICAgICBidWYuYnVmZmVyLFxuICAgICAgICAgICAgcG9pbnRfbGVuXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gdGFibGVJdGVyYXRlT25lKGl0ZXJfaWQsIGRlc2VyaWFsaXplUm93KTtcbiAgICAgICAgfSxcbiAgICAgICAgZGVsZXRlOiAoY29sVmFsKSA9PiB7XG4gICAgICAgICAgaWYgKGNvbFZhbC5sZW5ndGggIT09IG51bUNvbHVtbnMpXG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwid3JvbmcgbnVtYmVyIG9mIGVsZW1lbnRzXCIpO1xuICAgICAgICAgIGNvbnN0IGJ1ZiA9IExFQUZfQlVGO1xuICAgICAgICAgIGNvbnN0IHBvaW50X2xlbiA9IHNlcmlhbGl6ZVBvaW50KGJ1ZiwgY29sVmFsKTtcbiAgICAgICAgICBjb25zdCBudW0gPSBzeXMuZGF0YXN0b3JlX2RlbGV0ZV9ieV9pbmRleF9zY2FuX3BvaW50X2JzYXRuKFxuICAgICAgICAgICAgaW5kZXhfaWQsXG4gICAgICAgICAgICBidWYuYnVmZmVyLFxuICAgICAgICAgICAgcG9pbnRfbGVuXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gbnVtID4gMDtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIGlmIChpc1ByaW1hcnlLZXkpIHtcbiAgICAgICAgYmFzZS51cGRhdGUgPSAocm93KSA9PiB7XG4gICAgICAgICAgY29uc3QgYnVmID0gTEVBRl9CVUY7XG4gICAgICAgICAgQklOQVJZX1dSSVRFUi5yZXNldChidWYpO1xuICAgICAgICAgIHNlcmlhbGl6ZVJvdyhCSU5BUllfV1JJVEVSLCByb3cpO1xuICAgICAgICAgIHN5cy5kYXRhc3RvcmVfdXBkYXRlX2JzYXRuKFxuICAgICAgICAgICAgdGFibGVfaWQsXG4gICAgICAgICAgICBpbmRleF9pZCxcbiAgICAgICAgICAgIGJ1Zi5idWZmZXIsXG4gICAgICAgICAgICBCSU5BUllfV1JJVEVSLm9mZnNldFxuICAgICAgICAgICk7XG4gICAgICAgICAgaW50ZWdyYXRlR2VuZXJhdGVkQ29sdW1ucz8uKHJvdywgYnVmLnZpZXcpO1xuICAgICAgICAgIHJldHVybiByb3c7XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBpbmRleCA9IGJhc2U7XG4gICAgfSBlbHNlIGlmIChzZXJpYWxpemVTaW5nbGVQb2ludCkge1xuICAgICAgY29uc3QgcmF3SW5kZXggPSB7XG4gICAgICAgIGZpbHRlcjogKHJhbmdlKSA9PiB7XG4gICAgICAgICAgY29uc3QgYnVmID0gTEVBRl9CVUY7XG4gICAgICAgICAgY29uc3QgcG9pbnRfbGVuID0gc2VyaWFsaXplU2luZ2xlUG9pbnQoYnVmLCByYW5nZSk7XG4gICAgICAgICAgY29uc3QgaXRlcl9pZCA9IHN5cy5kYXRhc3RvcmVfaW5kZXhfc2Nhbl9wb2ludF9ic2F0bihcbiAgICAgICAgICAgIGluZGV4X2lkLFxuICAgICAgICAgICAgYnVmLmJ1ZmZlcixcbiAgICAgICAgICAgIHBvaW50X2xlblxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIHRhYmxlSXRlcmF0b3IoaXRlcl9pZCwgZGVzZXJpYWxpemVSb3cpO1xuICAgICAgICB9LFxuICAgICAgICBkZWxldGU6IChyYW5nZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGJ1ZiA9IExFQUZfQlVGO1xuICAgICAgICAgIGNvbnN0IHBvaW50X2xlbiA9IHNlcmlhbGl6ZVNpbmdsZVBvaW50KGJ1ZiwgcmFuZ2UpO1xuICAgICAgICAgIHJldHVybiBzeXMuZGF0YXN0b3JlX2RlbGV0ZV9ieV9pbmRleF9zY2FuX3BvaW50X2JzYXRuKFxuICAgICAgICAgICAgaW5kZXhfaWQsXG4gICAgICAgICAgICBidWYuYnVmZmVyLFxuICAgICAgICAgICAgcG9pbnRfbGVuXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIGlmIChpc0hhc2hJbmRleCkge1xuICAgICAgICBpbmRleCA9IHJhd0luZGV4O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaW5kZXggPSByYXdJbmRleDtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzSGFzaEluZGV4KSB7XG4gICAgICBpbmRleCA9IHtcbiAgICAgICAgZmlsdGVyOiAocmFuZ2UpID0+IHtcbiAgICAgICAgICBjb25zdCBidWYgPSBMRUFGX0JVRjtcbiAgICAgICAgICBjb25zdCBwb2ludF9sZW4gPSBzZXJpYWxpemVQb2ludChidWYsIHJhbmdlKTtcbiAgICAgICAgICBjb25zdCBpdGVyX2lkID0gc3lzLmRhdGFzdG9yZV9pbmRleF9zY2FuX3BvaW50X2JzYXRuKFxuICAgICAgICAgICAgaW5kZXhfaWQsXG4gICAgICAgICAgICBidWYuYnVmZmVyLFxuICAgICAgICAgICAgcG9pbnRfbGVuXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gdGFibGVJdGVyYXRvcihpdGVyX2lkLCBkZXNlcmlhbGl6ZVJvdyk7XG4gICAgICAgIH0sXG4gICAgICAgIGRlbGV0ZTogKHJhbmdlKSA9PiB7XG4gICAgICAgICAgY29uc3QgYnVmID0gTEVBRl9CVUY7XG4gICAgICAgICAgY29uc3QgcG9pbnRfbGVuID0gc2VyaWFsaXplUG9pbnQoYnVmLCByYW5nZSk7XG4gICAgICAgICAgcmV0dXJuIHN5cy5kYXRhc3RvcmVfZGVsZXRlX2J5X2luZGV4X3NjYW5fcG9pbnRfYnNhdG4oXG4gICAgICAgICAgICBpbmRleF9pZCxcbiAgICAgICAgICAgIGJ1Zi5idWZmZXIsXG4gICAgICAgICAgICBwb2ludF9sZW5cbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBzZXJpYWxpemVSYW5nZSA9IChidWZmZXIsIHJhbmdlKSA9PiB7XG4gICAgICAgIGlmIChyYW5nZS5sZW5ndGggPiBudW1Db2x1bW5zKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwidG9vIG1hbnkgZWxlbWVudHNcIik7XG4gICAgICAgIEJJTkFSWV9XUklURVIucmVzZXQoYnVmZmVyKTtcbiAgICAgICAgY29uc3Qgd3JpdGVyID0gQklOQVJZX1dSSVRFUjtcbiAgICAgICAgY29uc3QgcHJlZml4X2VsZW1zID0gcmFuZ2UubGVuZ3RoIC0gMTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwcmVmaXhfZWxlbXM7IGkrKykge1xuICAgICAgICAgIGluZGV4U2VyaWFsaXplcnNbaV0od3JpdGVyLCByYW5nZVtpXSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcnN0YXJ0T2Zmc2V0ID0gd3JpdGVyLm9mZnNldDtcbiAgICAgICAgY29uc3QgdGVybSA9IHJhbmdlW3JhbmdlLmxlbmd0aCAtIDFdO1xuICAgICAgICBjb25zdCBzZXJpYWxpemVUZXJtID0gaW5kZXhTZXJpYWxpemVyc1tyYW5nZS5sZW5ndGggLSAxXTtcbiAgICAgICAgaWYgKHRlcm0gaW5zdGFuY2VvZiBSYW5nZSkge1xuICAgICAgICAgIGNvbnN0IHdyaXRlQm91bmQgPSAoYm91bmQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHRhZ3MgPSB7IGluY2x1ZGVkOiAwLCBleGNsdWRlZDogMSwgdW5ib3VuZGVkOiAyIH07XG4gICAgICAgICAgICB3cml0ZXIud3JpdGVVOCh0YWdzW2JvdW5kLnRhZ10pO1xuICAgICAgICAgICAgaWYgKGJvdW5kLnRhZyAhPT0gXCJ1bmJvdW5kZWRcIikgc2VyaWFsaXplVGVybSh3cml0ZXIsIGJvdW5kLnZhbHVlKTtcbiAgICAgICAgICB9O1xuICAgICAgICAgIHdyaXRlQm91bmQodGVybS5mcm9tKTtcbiAgICAgICAgICBjb25zdCByc3RhcnRMZW4gPSB3cml0ZXIub2Zmc2V0IC0gcnN0YXJ0T2Zmc2V0O1xuICAgICAgICAgIHdyaXRlQm91bmQodGVybS50byk7XG4gICAgICAgICAgY29uc3QgcmVuZExlbiA9IHdyaXRlci5vZmZzZXQgLSByc3RhcnRMZW47XG4gICAgICAgICAgcmV0dXJuIFtyc3RhcnRPZmZzZXQsIHByZWZpeF9lbGVtcywgcnN0YXJ0TGVuLCByZW5kTGVuXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB3cml0ZXIud3JpdGVVOCgwKTtcbiAgICAgICAgICBzZXJpYWxpemVUZXJtKHdyaXRlciwgdGVybSk7XG4gICAgICAgICAgY29uc3QgcnN0YXJ0TGVuID0gd3JpdGVyLm9mZnNldDtcbiAgICAgICAgICBjb25zdCByZW5kTGVuID0gMDtcbiAgICAgICAgICByZXR1cm4gW3JzdGFydE9mZnNldCwgcHJlZml4X2VsZW1zLCByc3RhcnRMZW4sIHJlbmRMZW5dO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgaW5kZXggPSB7XG4gICAgICAgIGZpbHRlcjogKHJhbmdlKSA9PiB7XG4gICAgICAgICAgaWYgKHJhbmdlLmxlbmd0aCA9PT0gbnVtQ29sdW1ucykge1xuICAgICAgICAgICAgY29uc3QgYnVmID0gTEVBRl9CVUY7XG4gICAgICAgICAgICBjb25zdCBwb2ludF9sZW4gPSBzZXJpYWxpemVQb2ludChidWYsIHJhbmdlKTtcbiAgICAgICAgICAgIGNvbnN0IGl0ZXJfaWQgPSBzeXMuZGF0YXN0b3JlX2luZGV4X3NjYW5fcG9pbnRfYnNhdG4oXG4gICAgICAgICAgICAgIGluZGV4X2lkLFxuICAgICAgICAgICAgICBidWYuYnVmZmVyLFxuICAgICAgICAgICAgICBwb2ludF9sZW5cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm4gdGFibGVJdGVyYXRvcihpdGVyX2lkLCBkZXNlcmlhbGl6ZVJvdyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZiA9IExFQUZfQlVGO1xuICAgICAgICAgICAgY29uc3QgYXJncyA9IHNlcmlhbGl6ZVJhbmdlKGJ1ZiwgcmFuZ2UpO1xuICAgICAgICAgICAgY29uc3QgaXRlcl9pZCA9IHN5cy5kYXRhc3RvcmVfaW5kZXhfc2Nhbl9yYW5nZV9ic2F0bihcbiAgICAgICAgICAgICAgaW5kZXhfaWQsXG4gICAgICAgICAgICAgIGJ1Zi5idWZmZXIsXG4gICAgICAgICAgICAgIC4uLmFyZ3NcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByZXR1cm4gdGFibGVJdGVyYXRvcihpdGVyX2lkLCBkZXNlcmlhbGl6ZVJvdyk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBkZWxldGU6IChyYW5nZSkgPT4ge1xuICAgICAgICAgIGlmIChyYW5nZS5sZW5ndGggPT09IG51bUNvbHVtbnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGJ1ZiA9IExFQUZfQlVGO1xuICAgICAgICAgICAgY29uc3QgcG9pbnRfbGVuID0gc2VyaWFsaXplUG9pbnQoYnVmLCByYW5nZSk7XG4gICAgICAgICAgICByZXR1cm4gc3lzLmRhdGFzdG9yZV9kZWxldGVfYnlfaW5kZXhfc2Nhbl9wb2ludF9ic2F0bihcbiAgICAgICAgICAgICAgaW5kZXhfaWQsXG4gICAgICAgICAgICAgIGJ1Zi5idWZmZXIsXG4gICAgICAgICAgICAgIHBvaW50X2xlblxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgYnVmID0gTEVBRl9CVUY7XG4gICAgICAgICAgICBjb25zdCBhcmdzID0gc2VyaWFsaXplUmFuZ2UoYnVmLCByYW5nZSk7XG4gICAgICAgICAgICByZXR1cm4gc3lzLmRhdGFzdG9yZV9kZWxldGVfYnlfaW5kZXhfc2Nhbl9yYW5nZV9ic2F0bihcbiAgICAgICAgICAgICAgaW5kZXhfaWQsXG4gICAgICAgICAgICAgIGJ1Zi5idWZmZXIsXG4gICAgICAgICAgICAgIC4uLmFyZ3NcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAoT2JqZWN0Lmhhc093bih0YWJsZVZpZXcsIGFjY2Vzc29yTmFtZSkpIHtcbiAgICAgIGZyZWV6ZShPYmplY3QuYXNzaWduKHRhYmxlVmlld1thY2Nlc3Nvck5hbWVdLCBpbmRleCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0YWJsZVZpZXdbYWNjZXNzb3JOYW1lXSA9IGZyZWV6ZShpbmRleCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBmcmVlemUodGFibGVWaWV3KTtcbn1cbmZ1bmN0aW9uKiB0YWJsZUl0ZXJhdG9yKGlkLCBkZXNlcmlhbGl6ZSkge1xuICB1c2luZyBpdGVyID0gbmV3IEl0ZXJhdG9ySGFuZGxlKGlkKTtcbiAgY29uc3QgaXRlckJ1ZiA9IHRha2VCdWYoKTtcbiAgdHJ5IHtcbiAgICBsZXQgYW10O1xuICAgIHdoaWxlIChhbXQgPSBpdGVyLmFkdmFuY2UoaXRlckJ1ZikpIHtcbiAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBCaW5hcnlSZWFkZXIoaXRlckJ1Zi52aWV3KTtcbiAgICAgIHdoaWxlIChyZWFkZXIub2Zmc2V0IDwgYW10KSB7XG4gICAgICAgIHlpZWxkIGRlc2VyaWFsaXplKHJlYWRlcik7XG4gICAgICB9XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIHJldHVybkJ1ZihpdGVyQnVmKTtcbiAgfVxufVxuZnVuY3Rpb24gdGFibGVJdGVyYXRlT25lKGlkLCBkZXNlcmlhbGl6ZSkge1xuICBjb25zdCBidWYgPSBMRUFGX0JVRjtcbiAgY29uc3QgcmV0ID0gYWR2YW5jZUl0ZXJSYXcoaWQsIGJ1Zik7XG4gIGlmIChyZXQgIT09IDApIHtcbiAgICBCSU5BUllfUkVBREVSLnJlc2V0KGJ1Zi52aWV3KTtcbiAgICByZXR1cm4gZGVzZXJpYWxpemUoQklOQVJZX1JFQURFUik7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBhZHZhbmNlSXRlclJhdyhpZCwgYnVmKSB7XG4gIHdoaWxlICh0cnVlKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiAwIHwgc3lzLnJvd19pdGVyX2JzYXRuX2FkdmFuY2UoaWQsIGJ1Zi5idWZmZXIpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChlICYmIHR5cGVvZiBlID09PSBcIm9iamVjdFwiICYmIGhhc093bihlLCBcIl9fYnVmZmVyX3Rvb19zbWFsbF9fXCIpKSB7XG4gICAgICAgIGJ1Zi5ncm93KGUuX19idWZmZXJfdG9vX3NtYWxsX18pO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG59XG52YXIgREVGQVVMVF9CVUZGRVJfQ0FQQUNJVFkgPSAzMiAqIDEwMjQgKiAyO1xudmFyIElURVJfQlVGUyA9IFtcbiAgbmV3IFJlc2l6YWJsZUJ1ZmZlcihERUZBVUxUX0JVRkZFUl9DQVBBQ0lUWSlcbl07XG52YXIgSVRFUl9CVUZfQ09VTlQgPSAxO1xuZnVuY3Rpb24gdGFrZUJ1ZigpIHtcbiAgcmV0dXJuIElURVJfQlVGX0NPVU5UID8gSVRFUl9CVUZTWy0tSVRFUl9CVUZfQ09VTlRdIDogbmV3IFJlc2l6YWJsZUJ1ZmZlcihERUZBVUxUX0JVRkZFUl9DQVBBQ0lUWSk7XG59XG5mdW5jdGlvbiByZXR1cm5CdWYoYnVmKSB7XG4gIElURVJfQlVGU1tJVEVSX0JVRl9DT1VOVCsrXSA9IGJ1Zjtcbn1cbnZhciBMRUFGX0JVRiA9IG5ldyBSZXNpemFibGVCdWZmZXIoREVGQVVMVF9CVUZGRVJfQ0FQQUNJVFkpO1xudmFyIEl0ZXJhdG9ySGFuZGxlID0gY2xhc3MgX0l0ZXJhdG9ySGFuZGxlIHtcbiAgI2lkO1xuICBzdGF0aWMgI2ZpbmFsaXphdGlvblJlZ2lzdHJ5ID0gbmV3IEZpbmFsaXphdGlvblJlZ2lzdHJ5KFxuICAgIHN5cy5yb3dfaXRlcl9ic2F0bl9jbG9zZVxuICApO1xuICBjb25zdHJ1Y3RvcihpZCkge1xuICAgIHRoaXMuI2lkID0gaWQ7XG4gICAgX0l0ZXJhdG9ySGFuZGxlLiNmaW5hbGl6YXRpb25SZWdpc3RyeS5yZWdpc3Rlcih0aGlzLCBpZCwgdGhpcyk7XG4gIH1cbiAgLyoqIFVucmVnaXN0ZXIgdGhpcyBvYmplY3Qgd2l0aCB0aGUgZmluYWxpemF0aW9uIHJlZ2lzdHJ5IGFuZCByZXR1cm4gdGhlIGlkICovXG4gICNkZXRhY2goKSB7XG4gICAgY29uc3QgaWQgPSB0aGlzLiNpZDtcbiAgICB0aGlzLiNpZCA9IC0xO1xuICAgIF9JdGVyYXRvckhhbmRsZS4jZmluYWxpemF0aW9uUmVnaXN0cnkudW5yZWdpc3Rlcih0aGlzKTtcbiAgICByZXR1cm4gaWQ7XG4gIH1cbiAgLyoqIENhbGwgYHJvd19pdGVyX2JzYXRuX2FkdmFuY2VgLCByZXR1cm5pbmcgMCBpZiB0aGlzIGl0ZXJhdG9yIGhhcyBiZWVuIGV4aGF1c3RlZC4gKi9cbiAgYWR2YW5jZShidWYpIHtcbiAgICBpZiAodGhpcy4jaWQgPT09IC0xKSByZXR1cm4gMDtcbiAgICBjb25zdCByZXQgPSBhZHZhbmNlSXRlclJhdyh0aGlzLiNpZCwgYnVmKTtcbiAgICBpZiAocmV0IDw9IDApIHRoaXMuI2RldGFjaCgpO1xuICAgIHJldHVybiByZXQgPCAwID8gLXJldCA6IHJldDtcbiAgfVxuICBbU3ltYm9sLmRpc3Bvc2VdKCkge1xuICAgIGlmICh0aGlzLiNpZCA+PSAwKSB7XG4gICAgICBjb25zdCBpZCA9IHRoaXMuI2RldGFjaCgpO1xuICAgICAgc3lzLnJvd19pdGVyX2JzYXRuX2Nsb3NlKGlkKTtcbiAgICB9XG4gIH1cbn07XG5cbi8vIHNyYy9zZXJ2ZXIvaHR0cF9pbnRlcm5hbC50c1xudmFyIHsgZnJlZXplOiBmcmVlemUyIH0gPSBPYmplY3Q7XG52YXIgdGV4dEVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTtcbnZhciB0ZXh0RGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcihcbiAgXCJ1dGYtOFwiXG4gIC8qIHsgZmF0YWw6IHRydWUgfSAqL1xuKTtcbnZhciBtYWtlUmVzcG9uc2UgPSBTeW1ib2woXCJtYWtlUmVzcG9uc2VcIik7XG52YXIgU3luY1Jlc3BvbnNlID0gY2xhc3MgX1N5bmNSZXNwb25zZSB7XG4gICNib2R5O1xuICAjaW5uZXI7XG4gIGNvbnN0cnVjdG9yKGJvZHksIGluaXQpIHtcbiAgICBpZiAoYm9keSA9PSBudWxsKSB7XG4gICAgICB0aGlzLiNib2R5ID0gbnVsbDtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBib2R5ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICB0aGlzLiNib2R5ID0gYm9keTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy4jYm9keSA9IG5ldyBVaW50OEFycmF5KGJvZHkpLmJ1ZmZlcjtcbiAgICB9XG4gICAgdGhpcy4jaW5uZXIgPSB7XG4gICAgICBoZWFkZXJzOiBuZXcgSGVhZGVycyhpbml0Py5oZWFkZXJzKSxcbiAgICAgIHN0YXR1czogaW5pdD8uc3RhdHVzID8/IDIwMCxcbiAgICAgIHN0YXR1c1RleHQ6IGluaXQ/LnN0YXR1c1RleHQgPz8gXCJcIixcbiAgICAgIHR5cGU6IFwiZGVmYXVsdFwiLFxuICAgICAgdXJsOiBudWxsLFxuICAgICAgYWJvcnRlZDogZmFsc2VcbiAgICB9O1xuICB9XG4gIHN0YXRpYyBbbWFrZVJlc3BvbnNlXShib2R5LCBpbm5lcikge1xuICAgIGNvbnN0IG1lID0gbmV3IF9TeW5jUmVzcG9uc2UoYm9keSk7XG4gICAgbWUuI2lubmVyID0gaW5uZXI7XG4gICAgcmV0dXJuIG1lO1xuICB9XG4gIGdldCBoZWFkZXJzKCkge1xuICAgIHJldHVybiB0aGlzLiNpbm5lci5oZWFkZXJzO1xuICB9XG4gIGdldCBzdGF0dXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuI2lubmVyLnN0YXR1cztcbiAgfVxuICBnZXQgc3RhdHVzVGV4dCgpIHtcbiAgICByZXR1cm4gdGhpcy4jaW5uZXIuc3RhdHVzVGV4dDtcbiAgfVxuICBnZXQgb2soKSB7XG4gICAgcmV0dXJuIDIwMCA8PSB0aGlzLiNpbm5lci5zdGF0dXMgJiYgdGhpcy4jaW5uZXIuc3RhdHVzIDw9IDI5OTtcbiAgfVxuICBnZXQgdXJsKCkge1xuICAgIHJldHVybiB0aGlzLiNpbm5lci51cmwgPz8gXCJcIjtcbiAgfVxuICBnZXQgdHlwZSgpIHtcbiAgICByZXR1cm4gdGhpcy4jaW5uZXIudHlwZTtcbiAgfVxuICBhcnJheUJ1ZmZlcigpIHtcbiAgICByZXR1cm4gdGhpcy5ieXRlcygpLmJ1ZmZlcjtcbiAgfVxuICBieXRlcygpIHtcbiAgICBpZiAodGhpcy4jYm9keSA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLiNib2R5ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICByZXR1cm4gdGV4dEVuY29kZXIuZW5jb2RlKHRoaXMuI2JvZHkpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkodGhpcy4jYm9keSk7XG4gICAgfVxuICB9XG4gIGpzb24oKSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UodGhpcy50ZXh0KCkpO1xuICB9XG4gIHRleHQoKSB7XG4gICAgaWYgKHRoaXMuI2JvZHkgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIFwiXCI7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy4jYm9keSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgcmV0dXJuIHRoaXMuI2JvZHk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0ZXh0RGVjb2Rlci5kZWNvZGUodGhpcy4jYm9keSk7XG4gICAgfVxuICB9XG59O1xudmFyIHJlcXVlc3RCYXNlU2l6ZSA9IGJzYXRuQmFzZVNpemUoeyB0eXBlczogW10gfSwgSHR0cFJlcXVlc3QuYWxnZWJyYWljVHlwZSk7XG52YXIgbWV0aG9kcyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKFtcbiAgW1wiR0VUXCIsIHsgdGFnOiBcIkdldFwiIH1dLFxuICBbXCJIRUFEXCIsIHsgdGFnOiBcIkhlYWRcIiB9XSxcbiAgW1wiUE9TVFwiLCB7IHRhZzogXCJQb3N0XCIgfV0sXG4gIFtcIlBVVFwiLCB7IHRhZzogXCJQdXRcIiB9XSxcbiAgW1wiREVMRVRFXCIsIHsgdGFnOiBcIkRlbGV0ZVwiIH1dLFxuICBbXCJDT05ORUNUXCIsIHsgdGFnOiBcIkNvbm5lY3RcIiB9XSxcbiAgW1wiT1BUSU9OU1wiLCB7IHRhZzogXCJPcHRpb25zXCIgfV0sXG4gIFtcIlRSQUNFXCIsIHsgdGFnOiBcIlRyYWNlXCIgfV0sXG4gIFtcIlBBVENIXCIsIHsgdGFnOiBcIlBhdGNoXCIgfV1cbl0pO1xuZnVuY3Rpb24gZmV0Y2godXJsLCBpbml0ID0ge30pIHtcbiAgY29uc3QgbWV0aG9kID0gbWV0aG9kcy5nZXQoaW5pdC5tZXRob2Q/LnRvVXBwZXJDYXNlKCkgPz8gXCJHRVRcIikgPz8ge1xuICAgIHRhZzogXCJFeHRlbnNpb25cIixcbiAgICB2YWx1ZTogaW5pdC5tZXRob2RcbiAgfTtcbiAgY29uc3QgaGVhZGVycyA9IHtcbiAgICAvLyBhbnlzIGJlY2F1c2UgdGhlIHR5cGluZ3MgYXJlIHdvbmt5IC0gc2VlIGNvbW1lbnQgaW4gU3luY1Jlc3BvbnNlLmNvbnN0cnVjdG9yXG4gICAgZW50cmllczogaGVhZGVyc1RvTGlzdChuZXcgSGVhZGVycyhpbml0LmhlYWRlcnMpKS5mbGF0TWFwKChbaywgdl0pID0+IEFycmF5LmlzQXJyYXkodikgPyB2Lm1hcCgodjIpID0+IFtrLCB2Ml0pIDogW1trLCB2XV0pLm1hcCgoW25hbWUsIHZhbHVlXSkgPT4gKHsgbmFtZSwgdmFsdWU6IHRleHRFbmNvZGVyLmVuY29kZSh2YWx1ZSkgfSkpXG4gIH07XG4gIGNvbnN0IHVyaSA9IFwiXCIgKyB1cmw7XG4gIGNvbnN0IHJlcXVlc3QgPSBmcmVlemUyKHtcbiAgICBtZXRob2QsXG4gICAgaGVhZGVycyxcbiAgICB0aW1lb3V0OiBpbml0LnRpbWVvdXQsXG4gICAgdXJpLFxuICAgIHZlcnNpb246IHsgdGFnOiBcIkh0dHAxMVwiIH1cbiAgfSk7XG4gIGNvbnN0IHJlcXVlc3RCdWYgPSBuZXcgQmluYXJ5V3JpdGVyKHJlcXVlc3RCYXNlU2l6ZSk7XG4gIEh0dHBSZXF1ZXN0LnNlcmlhbGl6ZShyZXF1ZXN0QnVmLCByZXF1ZXN0KTtcbiAgY29uc3QgYm9keSA9IGluaXQuYm9keSA9PSBudWxsID8gbmV3IFVpbnQ4QXJyYXkoKSA6IHR5cGVvZiBpbml0LmJvZHkgPT09IFwic3RyaW5nXCIgPyBpbml0LmJvZHkgOiBuZXcgVWludDhBcnJheShpbml0LmJvZHkpO1xuICBjb25zdCBbcmVzcG9uc2VCdWYsIHJlc3BvbnNlQm9keV0gPSBzeXMucHJvY2VkdXJlX2h0dHBfcmVxdWVzdChcbiAgICByZXF1ZXN0QnVmLmdldEJ1ZmZlcigpLFxuICAgIGJvZHlcbiAgKTtcbiAgY29uc3QgcmVzcG9uc2UgPSBIdHRwUmVzcG9uc2UuZGVzZXJpYWxpemUobmV3IEJpbmFyeVJlYWRlcihyZXNwb25zZUJ1ZikpO1xuICByZXR1cm4gU3luY1Jlc3BvbnNlW21ha2VSZXNwb25zZV0ocmVzcG9uc2VCb2R5LCB7XG4gICAgdHlwZTogXCJiYXNpY1wiLFxuICAgIHVybDogdXJpLFxuICAgIHN0YXR1czogcmVzcG9uc2UuY29kZSxcbiAgICBzdGF0dXNUZXh0OiAoMCwgaW1wb3J0X3N0YXR1c2VzLmRlZmF1bHQpKHJlc3BvbnNlLmNvZGUpLFxuICAgIGhlYWRlcnM6IG5ldyBIZWFkZXJzKCksXG4gICAgYWJvcnRlZDogZmFsc2VcbiAgfSk7XG59XG5mcmVlemUyKGZldGNoKTtcbnZhciBodHRwQ2xpZW50ID0gZnJlZXplMih7IGZldGNoIH0pO1xuXG4vLyBzcmMvc2VydmVyL3Byb2NlZHVyZXMudHNcbmZ1bmN0aW9uIG1ha2VQcm9jZWR1cmVFeHBvcnQoY3R4LCBvcHRzLCBwYXJhbXMsIHJldCwgZm4pIHtcbiAgY29uc3QgbmFtZSA9IG9wdHM/Lm5hbWU7XG4gIGNvbnN0IHByb2NlZHVyZUV4cG9ydCA9ICguLi5hcmdzKSA9PiBmbiguLi5hcmdzKTtcbiAgcHJvY2VkdXJlRXhwb3J0W2V4cG9ydENvbnRleHRdID0gY3R4O1xuICBwcm9jZWR1cmVFeHBvcnRbcmVnaXN0ZXJFeHBvcnRdID0gKGN0eDIsIGV4cG9ydE5hbWUpID0+IHtcbiAgICByZWdpc3RlclByb2NlZHVyZShjdHgyLCBuYW1lID8/IGV4cG9ydE5hbWUsIHBhcmFtcywgcmV0LCBmbik7XG4gICAgY3R4Mi5mdW5jdGlvbkV4cG9ydHMuc2V0KFxuICAgICAgcHJvY2VkdXJlRXhwb3J0LFxuICAgICAgbmFtZSA/PyBleHBvcnROYW1lXG4gICAgKTtcbiAgfTtcbiAgcmV0dXJuIHByb2NlZHVyZUV4cG9ydDtcbn1cbnZhciBUcmFuc2FjdGlvbkN0eEltcGwgPSBjbGFzcyBUcmFuc2FjdGlvbkN0eCBleHRlbmRzIFJlZHVjZXJDdHhJbXBsIHtcbn07XG5mdW5jdGlvbiByZWdpc3RlclByb2NlZHVyZShjdHgsIGV4cG9ydE5hbWUsIHBhcmFtcywgcmV0LCBmbiwgb3B0cykge1xuICBjdHguZGVmaW5lRnVuY3Rpb24oZXhwb3J0TmFtZSk7XG4gIGNvbnN0IHBhcmFtc1R5cGUgPSB7XG4gICAgZWxlbWVudHM6IE9iamVjdC5lbnRyaWVzKHBhcmFtcykubWFwKChbbiwgY10pID0+ICh7XG4gICAgICBuYW1lOiBuLFxuICAgICAgYWxnZWJyYWljVHlwZTogY3R4LnJlZ2lzdGVyVHlwZXNSZWN1cnNpdmVseShcbiAgICAgICAgXCJ0eXBlQnVpbGRlclwiIGluIGMgPyBjLnR5cGVCdWlsZGVyIDogY1xuICAgICAgKS5hbGdlYnJhaWNUeXBlXG4gICAgfSkpXG4gIH07XG4gIGNvbnN0IHJldHVyblR5cGUgPSBjdHgucmVnaXN0ZXJUeXBlc1JlY3Vyc2l2ZWx5KHJldCkuYWxnZWJyYWljVHlwZTtcbiAgY3R4Lm1vZHVsZURlZi5wcm9jZWR1cmVzLnB1c2goe1xuICAgIHNvdXJjZU5hbWU6IGV4cG9ydE5hbWUsXG4gICAgcGFyYW1zOiBwYXJhbXNUeXBlLFxuICAgIHJldHVyblR5cGUsXG4gICAgdmlzaWJpbGl0eTogRnVuY3Rpb25WaXNpYmlsaXR5LkNsaWVudENhbGxhYmxlXG4gIH0pO1xuICBjb25zdCB7IHR5cGVzcGFjZSB9ID0gY3R4O1xuICBjdHgucHJvY2VkdXJlcy5wdXNoKHtcbiAgICBmbixcbiAgICBkZXNlcmlhbGl6ZUFyZ3M6IFByb2R1Y3RUeXBlLm1ha2VEZXNlcmlhbGl6ZXIocGFyYW1zVHlwZSwgdHlwZXNwYWNlKSxcbiAgICBzZXJpYWxpemVSZXR1cm46IEFsZ2VicmFpY1R5cGUubWFrZVNlcmlhbGl6ZXIocmV0dXJuVHlwZSwgdHlwZXNwYWNlKSxcbiAgICByZXR1cm5UeXBlQmFzZVNpemU6IGJzYXRuQmFzZVNpemUodHlwZXNwYWNlLCByZXR1cm5UeXBlKVxuICB9KTtcbn1cbmZ1bmN0aW9uIGNhbGxQcm9jZWR1cmUobW9kdWxlQ3R4LCBpZCwgc2VuZGVyLCBjb25uZWN0aW9uSWQsIHRpbWVzdGFtcCwgYXJnc0J1ZiwgZGJWaWV3KSB7XG4gIGNvbnN0IHsgZm4sIGRlc2VyaWFsaXplQXJncywgc2VyaWFsaXplUmV0dXJuLCByZXR1cm5UeXBlQmFzZVNpemUgfSA9IG1vZHVsZUN0eC5wcm9jZWR1cmVzW2lkXTtcbiAgY29uc3QgYXJncyA9IGRlc2VyaWFsaXplQXJncyhuZXcgQmluYXJ5UmVhZGVyKGFyZ3NCdWYpKTtcbiAgY29uc3QgY3R4ID0gbmV3IFByb2NlZHVyZUN0eEltcGwoXG4gICAgc2VuZGVyLFxuICAgIHRpbWVzdGFtcCxcbiAgICBjb25uZWN0aW9uSWQsXG4gICAgZGJWaWV3XG4gICk7XG4gIGNvbnN0IHJldCA9IGNhbGxVc2VyRnVuY3Rpb24oZm4sIGN0eCwgYXJncyk7XG4gIGNvbnN0IHJldEJ1ZiA9IG5ldyBCaW5hcnlXcml0ZXIocmV0dXJuVHlwZUJhc2VTaXplKTtcbiAgc2VyaWFsaXplUmV0dXJuKHJldEJ1ZiwgcmV0KTtcbiAgcmV0dXJuIHJldEJ1Zi5nZXRCdWZmZXIoKTtcbn1cbnZhciBQcm9jZWR1cmVDdHhJbXBsID0gY2xhc3MgUHJvY2VkdXJlQ3R4IHtcbiAgY29uc3RydWN0b3Ioc2VuZGVyLCB0aW1lc3RhbXAsIGNvbm5lY3Rpb25JZCwgZGJWaWV3KSB7XG4gICAgdGhpcy5zZW5kZXIgPSBzZW5kZXI7XG4gICAgdGhpcy50aW1lc3RhbXAgPSB0aW1lc3RhbXA7XG4gICAgdGhpcy5jb25uZWN0aW9uSWQgPSBjb25uZWN0aW9uSWQ7XG4gICAgdGhpcy4jZGJWaWV3ID0gZGJWaWV3O1xuICB9XG4gICNpZGVudGl0eTtcbiAgI3V1aWRDb3VudGVyO1xuICAjcmFuZG9tO1xuICAjZGJWaWV3O1xuICBnZXQgaWRlbnRpdHkoKSB7XG4gICAgcmV0dXJuIHRoaXMuI2lkZW50aXR5ID8/PSBuZXcgSWRlbnRpdHkoc3lzLmlkZW50aXR5KCkpO1xuICB9XG4gIGdldCByYW5kb20oKSB7XG4gICAgcmV0dXJuIHRoaXMuI3JhbmRvbSA/Pz0gbWFrZVJhbmRvbSh0aGlzLnRpbWVzdGFtcCk7XG4gIH1cbiAgZ2V0IGh0dHAoKSB7XG4gICAgcmV0dXJuIGh0dHBDbGllbnQ7XG4gIH1cbiAgd2l0aFR4KGJvZHkpIHtcbiAgICBjb25zdCBydW4gPSAoKSA9PiB7XG4gICAgICBjb25zdCB0aW1lc3RhbXAgPSBzeXMucHJvY2VkdXJlX3N0YXJ0X211dF90eCgpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgY3R4ID0gbmV3IFRyYW5zYWN0aW9uQ3R4SW1wbChcbiAgICAgICAgICB0aGlzLnNlbmRlcixcbiAgICAgICAgICBuZXcgVGltZXN0YW1wKHRpbWVzdGFtcCksXG4gICAgICAgICAgdGhpcy5jb25uZWN0aW9uSWQsXG4gICAgICAgICAgdGhpcy4jZGJWaWV3KClcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIGJvZHkoY3R4KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgc3lzLnByb2NlZHVyZV9hYm9ydF9tdXRfdHgoKTtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGxldCByZXMgPSBydW4oKTtcbiAgICB0cnkge1xuICAgICAgc3lzLnByb2NlZHVyZV9jb21taXRfbXV0X3R4KCk7XG4gICAgICByZXR1cm4gcmVzO1xuICAgIH0gY2F0Y2gge1xuICAgIH1cbiAgICBjb25zb2xlLndhcm4oXCJjb21taXR0aW5nIGFub255bW91cyB0cmFuc2FjdGlvbiBmYWlsZWRcIik7XG4gICAgcmVzID0gcnVuKCk7XG4gICAgdHJ5IHtcbiAgICAgIHN5cy5wcm9jZWR1cmVfY29tbWl0X211dF90eCgpO1xuICAgICAgcmV0dXJuIHJlcztcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0cmFuc2FjdGlvbiByZXRyeSBmYWlsZWQgYWdhaW5cIiwgeyBjYXVzZTogZSB9KTtcbiAgICB9XG4gIH1cbiAgbmV3VXVpZFY0KCkge1xuICAgIGNvbnN0IGJ5dGVzID0gdGhpcy5yYW5kb20uZmlsbChuZXcgVWludDhBcnJheSgxNikpO1xuICAgIHJldHVybiBVdWlkLmZyb21SYW5kb21CeXRlc1Y0KGJ5dGVzKTtcbiAgfVxuICBuZXdVdWlkVjcoKSB7XG4gICAgY29uc3QgYnl0ZXMgPSB0aGlzLnJhbmRvbS5maWxsKG5ldyBVaW50OEFycmF5KDQpKTtcbiAgICBjb25zdCBjb3VudGVyID0gdGhpcy4jdXVpZENvdW50ZXIgPz89IHsgdmFsdWU6IDAgfTtcbiAgICByZXR1cm4gVXVpZC5mcm9tQ291bnRlclY3KGNvdW50ZXIsIHRoaXMudGltZXN0YW1wLCBieXRlcyk7XG4gIH1cbn07XG5cbi8vIHNyYy9zZXJ2ZXIvcmVkdWNlcnMudHNcbmZ1bmN0aW9uIG1ha2VSZWR1Y2VyRXhwb3J0KGN0eCwgb3B0cywgcGFyYW1zLCBmbiwgbGlmZWN5Y2xlKSB7XG4gIGNvbnN0IHJlZHVjZXJFeHBvcnQgPSAoLi4uYXJncykgPT4gZm4oLi4uYXJncyk7XG4gIHJlZHVjZXJFeHBvcnRbZXhwb3J0Q29udGV4dF0gPSBjdHg7XG4gIHJlZHVjZXJFeHBvcnRbcmVnaXN0ZXJFeHBvcnRdID0gKGN0eDIsIGV4cG9ydE5hbWUpID0+IHtcbiAgICByZWdpc3RlclJlZHVjZXIoY3R4MiwgZXhwb3J0TmFtZSwgcGFyYW1zLCBmbiwgb3B0cywgbGlmZWN5Y2xlKTtcbiAgICBjdHgyLmZ1bmN0aW9uRXhwb3J0cy5zZXQoXG4gICAgICByZWR1Y2VyRXhwb3J0LFxuICAgICAgZXhwb3J0TmFtZVxuICAgICk7XG4gIH07XG4gIHJldHVybiByZWR1Y2VyRXhwb3J0O1xufVxuZnVuY3Rpb24gcmVnaXN0ZXJSZWR1Y2VyKGN0eCwgZXhwb3J0TmFtZSwgcGFyYW1zLCBmbiwgb3B0cywgbGlmZWN5Y2xlKSB7XG4gIGN0eC5kZWZpbmVGdW5jdGlvbihleHBvcnROYW1lKTtcbiAgaWYgKCEocGFyYW1zIGluc3RhbmNlb2YgUm93QnVpbGRlcikpIHtcbiAgICBwYXJhbXMgPSBuZXcgUm93QnVpbGRlcihwYXJhbXMpO1xuICB9XG4gIGlmIChwYXJhbXMudHlwZU5hbWUgPT09IHZvaWQgMCkge1xuICAgIHBhcmFtcy50eXBlTmFtZSA9IHRvUGFzY2FsQ2FzZShleHBvcnROYW1lKTtcbiAgfVxuICBjb25zdCByZWYgPSBjdHgucmVnaXN0ZXJUeXBlc1JlY3Vyc2l2ZWx5KHBhcmFtcyk7XG4gIGNvbnN0IHBhcmFtc1R5cGUgPSBjdHgucmVzb2x2ZVR5cGUocmVmKS52YWx1ZTtcbiAgY29uc3QgaXNMaWZlY3ljbGUgPSBsaWZlY3ljbGUgIT0gbnVsbDtcbiAgY3R4Lm1vZHVsZURlZi5yZWR1Y2Vycy5wdXNoKHtcbiAgICBzb3VyY2VOYW1lOiBleHBvcnROYW1lLFxuICAgIHBhcmFtczogcGFyYW1zVHlwZSxcbiAgICAvL01vZHVsZURlZiB2YWxpZGF0aW9uIGNvZGUgaXMgcmVzcG9uc2libGUgdG8gbWFyayBwcml2YXRlIHJlZHVjZXJzXG4gICAgdmlzaWJpbGl0eTogRnVuY3Rpb25WaXNpYmlsaXR5LkNsaWVudENhbGxhYmxlLFxuICAgIC8vSGFyZGNvZGVkIGZvciBub3cgLSByZWR1Y2VycyBkbyBub3QgcmV0dXJuIHZhbHVlcyB5ZXRcbiAgICBva1JldHVyblR5cGU6IEFsZ2VicmFpY1R5cGUuUHJvZHVjdCh7IGVsZW1lbnRzOiBbXSB9KSxcbiAgICBlcnJSZXR1cm5UeXBlOiBBbGdlYnJhaWNUeXBlLlN0cmluZ1xuICB9KTtcbiAgaWYgKG9wdHM/Lm5hbWUgIT0gbnVsbCkge1xuICAgIGN0eC5tb2R1bGVEZWYuZXhwbGljaXROYW1lcy5lbnRyaWVzLnB1c2goe1xuICAgICAgdGFnOiBcIkZ1bmN0aW9uXCIsXG4gICAgICB2YWx1ZToge1xuICAgICAgICBzb3VyY2VOYW1lOiBleHBvcnROYW1lLFxuICAgICAgICBjYW5vbmljYWxOYW1lOiBvcHRzLm5hbWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuICBpZiAoaXNMaWZlY3ljbGUpIHtcbiAgICBjdHgubW9kdWxlRGVmLmxpZmVDeWNsZVJlZHVjZXJzLnB1c2goe1xuICAgICAgbGlmZWN5Y2xlU3BlYzogbGlmZWN5Y2xlLFxuICAgICAgZnVuY3Rpb25OYW1lOiBleHBvcnROYW1lXG4gICAgfSk7XG4gIH1cbiAgaWYgKCFmbi5uYW1lKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGZuLCBcIm5hbWVcIiwgeyB2YWx1ZTogZXhwb3J0TmFtZSwgd3JpdGFibGU6IGZhbHNlIH0pO1xuICB9XG4gIGN0eC5yZWR1Y2Vycy5wdXNoKGZuKTtcbn1cblxuLy8gc3JjL3NlcnZlci9zY2hlbWEudHNcbnZhciBTY2hlbWFJbm5lciA9IGNsYXNzIGV4dGVuZHMgTW9kdWxlQ29udGV4dCB7XG4gIHNjaGVtYVR5cGU7XG4gIGV4aXN0aW5nRnVuY3Rpb25zID0gLyogQF9fUFVSRV9fICovIG5ldyBTZXQoKTtcbiAgcmVkdWNlcnMgPSBbXTtcbiAgcHJvY2VkdXJlcyA9IFtdO1xuICB2aWV3cyA9IFtdO1xuICBhbm9uVmlld3MgPSBbXTtcbiAgLyoqXG4gICAqIE1hcHMgUmVkdWNlckV4cG9ydCBvYmplY3RzIHRvIHRoZSBuYW1lIG9mIHRoZSByZWR1Y2VyLlxuICAgKiBVc2VkIGZvciByZXNvbHZpbmcgdGhlIHJlZHVjZXJzIG9mIHNjaGVkdWxlZCB0YWJsZXMuXG4gICAqL1xuICBmdW5jdGlvbkV4cG9ydHMgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpO1xuICBwZW5kaW5nU2NoZWR1bGVzID0gW107XG4gIGNvbnN0cnVjdG9yKGdldFNjaGVtYVR5cGUpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuc2NoZW1hVHlwZSA9IGdldFNjaGVtYVR5cGUodGhpcyk7XG4gIH1cbiAgZGVmaW5lRnVuY3Rpb24obmFtZSkge1xuICAgIGlmICh0aGlzLmV4aXN0aW5nRnVuY3Rpb25zLmhhcyhuYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgYFRoZXJlIGlzIGFscmVhZHkgYSByZWR1Y2VyIG9yIHByb2NlZHVyZSB3aXRoIHRoZSBuYW1lICcke25hbWV9J2BcbiAgICAgICk7XG4gICAgfVxuICAgIHRoaXMuZXhpc3RpbmdGdW5jdGlvbnMuYWRkKG5hbWUpO1xuICB9XG4gIHJlc29sdmVTY2hlZHVsZXMoKSB7XG4gICAgZm9yIChjb25zdCB7IHJlZHVjZXIsIHNjaGVkdWxlQXRDb2wsIHRhYmxlTmFtZSB9IG9mIHRoaXMucGVuZGluZ1NjaGVkdWxlcykge1xuICAgICAgY29uc3QgZnVuY3Rpb25OYW1lID0gdGhpcy5mdW5jdGlvbkV4cG9ydHMuZ2V0KHJlZHVjZXIoKSk7XG4gICAgICBpZiAoZnVuY3Rpb25OYW1lID09PSB2b2lkIDApIHtcbiAgICAgICAgY29uc3QgbXNnID0gYFRhYmxlICR7dGFibGVOYW1lfSBkZWZpbmVzIGEgc2NoZWR1bGUsIGJ1dCBpdCBzZWVtcyBsaWtlIHRoZSBhc3NvY2lhdGVkIGZ1bmN0aW9uIHdhcyBub3QgZXhwb3J0ZWQuYDtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihtc2cpO1xuICAgICAgfVxuICAgICAgdGhpcy5tb2R1bGVEZWYuc2NoZWR1bGVzLnB1c2goe1xuICAgICAgICBzb3VyY2VOYW1lOiB2b2lkIDAsXG4gICAgICAgIHRhYmxlTmFtZSxcbiAgICAgICAgc2NoZWR1bGVBdENvbCxcbiAgICAgICAgZnVuY3Rpb25OYW1lXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn07XG52YXIgU2NoZW1hID0gY2xhc3Mge1xuICAjY3R4O1xuICBjb25zdHJ1Y3RvcihjdHgpIHtcbiAgICB0aGlzLiNjdHggPSBjdHg7XG4gIH1cbiAgW21vZHVsZUhvb2tzXShleHBvcnRzKSB7XG4gICAgY29uc3QgcmVnaXN0ZXJlZFNjaGVtYSA9IHRoaXMuI2N0eDtcbiAgICBmb3IgKGNvbnN0IFtuYW1lLCBtb2R1bGVFeHBvcnRdIG9mIE9iamVjdC5lbnRyaWVzKGV4cG9ydHMpKSB7XG4gICAgICBpZiAobmFtZSA9PT0gXCJkZWZhdWx0XCIpIGNvbnRpbnVlO1xuICAgICAgaWYgKCFpc01vZHVsZUV4cG9ydChtb2R1bGVFeHBvcnQpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgXCJleHBvcnRpbmcgc29tZXRoaW5nIHRoYXQgaXMgbm90IGEgc3BhY2V0aW1lIGV4cG9ydFwiXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBjaGVja0V4cG9ydENvbnRleHQobW9kdWxlRXhwb3J0LCByZWdpc3RlcmVkU2NoZW1hKTtcbiAgICAgIG1vZHVsZUV4cG9ydFtyZWdpc3RlckV4cG9ydF0ocmVnaXN0ZXJlZFNjaGVtYSwgbmFtZSk7XG4gICAgfVxuICAgIHJlZ2lzdGVyZWRTY2hlbWEucmVzb2x2ZVNjaGVkdWxlcygpO1xuICAgIHJldHVybiBtYWtlSG9va3MocmVnaXN0ZXJlZFNjaGVtYSk7XG4gIH1cbiAgZ2V0IHNjaGVtYVR5cGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuI2N0eC5zY2hlbWFUeXBlO1xuICB9XG4gIGdldCBtb2R1bGVEZWYoKSB7XG4gICAgcmV0dXJuIHRoaXMuI2N0eC5tb2R1bGVEZWY7XG4gIH1cbiAgZ2V0IHR5cGVzcGFjZSgpIHtcbiAgICByZXR1cm4gdGhpcy4jY3R4LnR5cGVzcGFjZTtcbiAgfVxuICByZWR1Y2VyKC4uLmFyZ3MpIHtcbiAgICBsZXQgb3B0cywgcGFyYW1zID0ge30sIGZuO1xuICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgW2ZuXSA9IGFyZ3M7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOiB7XG4gICAgICAgIGxldCBhcmcxO1xuICAgICAgICBbYXJnMSwgZm5dID0gYXJncztcbiAgICAgICAgaWYgKHR5cGVvZiBhcmcxLm5hbWUgPT09IFwic3RyaW5nXCIpIG9wdHMgPSBhcmcxO1xuICAgICAgICBlbHNlIHBhcmFtcyA9IGFyZzE7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAzOlxuICAgICAgICBbb3B0cywgcGFyYW1zLCBmbl0gPSBhcmdzO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIG1ha2VSZWR1Y2VyRXhwb3J0KHRoaXMuI2N0eCwgb3B0cywgcGFyYW1zLCBmbik7XG4gIH1cbiAgaW5pdCguLi5hcmdzKSB7XG4gICAgbGV0IG9wdHMsIGZuO1xuICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgW2ZuXSA9IGFyZ3M7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOlxuICAgICAgICBbb3B0cywgZm5dID0gYXJncztcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiBtYWtlUmVkdWNlckV4cG9ydCh0aGlzLiNjdHgsIG9wdHMsIHt9LCBmbiwgTGlmZWN5Y2xlLkluaXQpO1xuICB9XG4gIGNsaWVudENvbm5lY3RlZCguLi5hcmdzKSB7XG4gICAgbGV0IG9wdHMsIGZuO1xuICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgW2ZuXSA9IGFyZ3M7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOlxuICAgICAgICBbb3B0cywgZm5dID0gYXJncztcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiBtYWtlUmVkdWNlckV4cG9ydCh0aGlzLiNjdHgsIG9wdHMsIHt9LCBmbiwgTGlmZWN5Y2xlLk9uQ29ubmVjdCk7XG4gIH1cbiAgY2xpZW50RGlzY29ubmVjdGVkKC4uLmFyZ3MpIHtcbiAgICBsZXQgb3B0cywgZm47XG4gICAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgICAgY2FzZSAxOlxuICAgICAgICBbZm5dID0gYXJncztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIFtvcHRzLCBmbl0gPSBhcmdzO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIG1ha2VSZWR1Y2VyRXhwb3J0KHRoaXMuI2N0eCwgb3B0cywge30sIGZuLCBMaWZlY3ljbGUuT25EaXNjb25uZWN0KTtcbiAgfVxuICB2aWV3KG9wdHMsIHJldCwgZm4pIHtcbiAgICByZXR1cm4gbWFrZVZpZXdFeHBvcnQodGhpcy4jY3R4LCBvcHRzLCB7fSwgcmV0LCBmbik7XG4gIH1cbiAgLy8gVE9ETzogcmUtZW5hYmxlIG9uY2UgcGFyYW1ldGVyaXplZCB2aWV3cyBhcmUgc3VwcG9ydGVkIGluIFNRTFxuICAvLyB2aWV3PFJldCBleHRlbmRzIFZpZXdSZXR1cm5UeXBlQnVpbGRlcj4oXG4gIC8vICAgb3B0czogVmlld09wdHMsXG4gIC8vICAgcmV0OiBSZXQsXG4gIC8vICAgZm46IFZpZXdGbjxTLCB7fSwgUmV0PlxuICAvLyApOiB2b2lkO1xuICAvLyB2aWV3PFBhcmFtcyBleHRlbmRzIFBhcmFtc09iaiwgUmV0IGV4dGVuZHMgVmlld1JldHVyblR5cGVCdWlsZGVyPihcbiAgLy8gICBvcHRzOiBWaWV3T3B0cyxcbiAgLy8gICBwYXJhbXM6IFBhcmFtcyxcbiAgLy8gICByZXQ6IFJldCxcbiAgLy8gICBmbjogVmlld0ZuPFMsIHt9LCBSZXQ+XG4gIC8vICk6IHZvaWQ7XG4gIC8vIHZpZXc8UGFyYW1zIGV4dGVuZHMgUGFyYW1zT2JqLCBSZXQgZXh0ZW5kcyBWaWV3UmV0dXJuVHlwZUJ1aWxkZXI+KFxuICAvLyAgIG9wdHM6IFZpZXdPcHRzLFxuICAvLyAgIHBhcmFtc09yUmV0OiBSZXQgfCBQYXJhbXMsXG4gIC8vICAgcmV0T3JGbjogVmlld0ZuPFMsIHt9LCBSZXQ+IHwgUmV0LFxuICAvLyAgIG1heWJlRm4/OiBWaWV3Rm48UywgUGFyYW1zLCBSZXQ+XG4gIC8vICk6IHZvaWQge1xuICAvLyAgIGlmICh0eXBlb2YgcmV0T3JGbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAvLyAgICAgZGVmaW5lVmlldyhuYW1lLCBmYWxzZSwge30sIHBhcmFtc09yUmV0IGFzIFJldCwgcmV0T3JGbik7XG4gIC8vICAgfSBlbHNlIHtcbiAgLy8gICAgIGRlZmluZVZpZXcobmFtZSwgZmFsc2UsIHBhcmFtc09yUmV0IGFzIFBhcmFtcywgcmV0T3JGbiwgbWF5YmVGbiEpO1xuICAvLyAgIH1cbiAgLy8gfVxuICBhbm9ueW1vdXNWaWV3KG9wdHMsIHJldCwgZm4pIHtcbiAgICByZXR1cm4gbWFrZUFub25WaWV3RXhwb3J0KHRoaXMuI2N0eCwgb3B0cywge30sIHJldCwgZm4pO1xuICB9XG4gIHByb2NlZHVyZSguLi5hcmdzKSB7XG4gICAgbGV0IG9wdHMsIHBhcmFtcyA9IHt9LCByZXQsIGZuO1xuICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgIGNhc2UgMjpcbiAgICAgICAgW3JldCwgZm5dID0gYXJncztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6IHtcbiAgICAgICAgbGV0IGFyZzE7XG4gICAgICAgIFthcmcxLCByZXQsIGZuXSA9IGFyZ3M7XG4gICAgICAgIGlmICh0eXBlb2YgYXJnMS5uYW1lID09PSBcInN0cmluZ1wiKSBvcHRzID0gYXJnMTtcbiAgICAgICAgZWxzZSBwYXJhbXMgPSBhcmcxO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgNDpcbiAgICAgICAgW29wdHMsIHBhcmFtcywgcmV0LCBmbl0gPSBhcmdzO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIG1ha2VQcm9jZWR1cmVFeHBvcnQodGhpcy4jY3R4LCBvcHRzLCBwYXJhbXMsIHJldCwgZm4pO1xuICB9XG4gIC8qKlxuICAgKiBCdW5kbGUgbXVsdGlwbGUgcmVkdWNlcnMsIHByb2NlZHVyZXMsIGV0YyBpbnRvIG9uZSB2YWx1ZSB0byBleHBvcnQuXG4gICAqIFRoZSBuYW1lIHRoZXkgd2lsbCBiZSBleHBvcnRlZCB3aXRoIGlzIHRoZWlyIGNvcnJlc3BvbmRpbmcga2V5IGluIHRoZSBgZXhwb3J0c2AgYXJndW1lbnQuXG4gICAqL1xuICBleHBvcnRHcm91cChleHBvcnRzKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIFtleHBvcnRDb250ZXh0XTogdGhpcy4jY3R4LFxuICAgICAgW3JlZ2lzdGVyRXhwb3J0XShjdHgsIF9leHBvcnROYW1lKSB7XG4gICAgICAgIGZvciAoY29uc3QgW2V4cG9ydE5hbWUsIG1vZHVsZUV4cG9ydF0gb2YgT2JqZWN0LmVudHJpZXMoZXhwb3J0cykpIHtcbiAgICAgICAgICBjaGVja0V4cG9ydENvbnRleHQobW9kdWxlRXhwb3J0LCBjdHgpO1xuICAgICAgICAgIG1vZHVsZUV4cG9ydFtyZWdpc3RlckV4cG9ydF0oY3R4LCBleHBvcnROYW1lKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gIH1cbiAgY2xpZW50VmlzaWJpbGl0eUZpbHRlciA9IHtcbiAgICBzcWw6IChmaWx0ZXIpID0+ICh7XG4gICAgICBbZXhwb3J0Q29udGV4dF06IHRoaXMuI2N0eCxcbiAgICAgIFtyZWdpc3RlckV4cG9ydF0oY3R4LCBfZXhwb3J0TmFtZSkge1xuICAgICAgICBjdHgubW9kdWxlRGVmLnJvd0xldmVsU2VjdXJpdHkucHVzaCh7IHNxbDogZmlsdGVyIH0pO1xuICAgICAgfVxuICAgIH0pXG4gIH07XG59O1xudmFyIHJlZ2lzdGVyRXhwb3J0ID0gU3ltYm9sKFwiU3BhY2V0aW1lREIucmVnaXN0ZXJFeHBvcnRcIik7XG52YXIgZXhwb3J0Q29udGV4dCA9IFN5bWJvbChcIlNwYWNldGltZURCLmV4cG9ydENvbnRleHRcIik7XG5mdW5jdGlvbiBpc01vZHVsZUV4cG9ydCh4KSB7XG4gIHJldHVybiAodHlwZW9mIHggPT09IFwiZnVuY3Rpb25cIiB8fCB0eXBlb2YgeCA9PT0gXCJvYmplY3RcIikgJiYgeCAhPT0gbnVsbCAmJiByZWdpc3RlckV4cG9ydCBpbiB4O1xufVxuZnVuY3Rpb24gY2hlY2tFeHBvcnRDb250ZXh0KGV4cCwgc2NoZW1hMikge1xuICBpZiAoZXhwW2V4cG9ydENvbnRleHRdICE9IG51bGwgJiYgZXhwW2V4cG9ydENvbnRleHRdICE9PSBzY2hlbWEyKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIm11bHRpcGxlIHNjaGVtYXMgYXJlIG5vdCBzdXBwb3J0ZWRcIik7XG4gIH1cbn1cbmZ1bmN0aW9uIHNjaGVtYSh0YWJsZXMsIG1vZHVsZVNldHRpbmdzKSB7XG4gIGNvbnN0IGN0eCA9IG5ldyBTY2hlbWFJbm5lcigoY3R4MikgPT4ge1xuICAgIGlmIChtb2R1bGVTZXR0aW5ncz8uQ0FTRV9DT05WRVJTSU9OX1BPTElDWSAhPSBudWxsKSB7XG4gICAgICBjdHgyLnNldENhc2VDb252ZXJzaW9uUG9saWN5KG1vZHVsZVNldHRpbmdzLkNBU0VfQ09OVkVSU0lPTl9QT0xJQ1kpO1xuICAgIH1cbiAgICBjb25zdCB0YWJsZVNjaGVtYXMgPSB7fTtcbiAgICBmb3IgKGNvbnN0IFthY2NOYW1lLCB0YWJsZTJdIG9mIE9iamVjdC5lbnRyaWVzKHRhYmxlcykpIHtcbiAgICAgIGNvbnN0IHRhYmxlRGVmID0gdGFibGUyLnRhYmxlRGVmKGN0eDIsIGFjY05hbWUpO1xuICAgICAgdGFibGVTY2hlbWFzW2FjY05hbWVdID0gdGFibGVUb1NjaGVtYShhY2NOYW1lLCB0YWJsZTIsIHRhYmxlRGVmKTtcbiAgICAgIGN0eDIubW9kdWxlRGVmLnRhYmxlcy5wdXNoKHRhYmxlRGVmKTtcbiAgICAgIGlmICh0YWJsZTIuc2NoZWR1bGUpIHtcbiAgICAgICAgY3R4Mi5wZW5kaW5nU2NoZWR1bGVzLnB1c2goe1xuICAgICAgICAgIC4uLnRhYmxlMi5zY2hlZHVsZSxcbiAgICAgICAgICB0YWJsZU5hbWU6IHRhYmxlRGVmLnNvdXJjZU5hbWVcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAodGFibGUyLnRhYmxlTmFtZSkge1xuICAgICAgICBjdHgyLm1vZHVsZURlZi5leHBsaWNpdE5hbWVzLmVudHJpZXMucHVzaCh7XG4gICAgICAgICAgdGFnOiBcIlRhYmxlXCIsXG4gICAgICAgICAgdmFsdWU6IHtcbiAgICAgICAgICAgIHNvdXJjZU5hbWU6IGFjY05hbWUsXG4gICAgICAgICAgICBjYW5vbmljYWxOYW1lOiB0YWJsZTIudGFibGVOYW1lXG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgdGFibGVzOiB0YWJsZVNjaGVtYXMgfTtcbiAgfSk7XG4gIHJldHVybiBuZXcgU2NoZW1hKGN0eCk7XG59XG5cbi8vIHNyYy9zZXJ2ZXIvY29uc29sZS50c1xudmFyIGltcG9ydF9vYmplY3RfaW5zcGVjdCA9IF9fdG9FU00ocmVxdWlyZV9vYmplY3RfaW5zcGVjdCgpKTtcbnZhciBmbXRMb2cgPSAoLi4uZGF0YSkgPT4gZGF0YS5tYXAoKHgpID0+IHR5cGVvZiB4ID09PSBcInN0cmluZ1wiID8geCA6ICgwLCBpbXBvcnRfb2JqZWN0X2luc3BlY3QuZGVmYXVsdCkoeCkpLmpvaW4oXCIgXCIpO1xudmFyIGNvbnNvbGVfbGV2ZWxfZXJyb3IgPSAwO1xudmFyIGNvbnNvbGVfbGV2ZWxfd2FybiA9IDE7XG52YXIgY29uc29sZV9sZXZlbF9pbmZvID0gMjtcbnZhciBjb25zb2xlX2xldmVsX2RlYnVnID0gMztcbnZhciBjb25zb2xlX2xldmVsX3RyYWNlID0gNDtcbnZhciB0aW1lck1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7XG52YXIgY29uc29sZTIgPSB7XG4gIC8vIEB0cy1leHBlY3QtZXJyb3Igd2Ugd2FudCBhIGJsYW5rIHByb3RvdHlwZSwgYnV0IHR5cGVzY3JpcHQgY29tcGxhaW5zXG4gIF9fcHJvdG9fXzoge30sXG4gIFtTeW1ib2wudG9TdHJpbmdUYWddOiBcImNvbnNvbGVcIixcbiAgYXNzZXJ0OiAoY29uZGl0aW9uID0gZmFsc2UsIC4uLmRhdGEpID0+IHtcbiAgICBpZiAoIWNvbmRpdGlvbikge1xuICAgICAgc3lzLmNvbnNvbGVfbG9nKGNvbnNvbGVfbGV2ZWxfZXJyb3IsIGZtdExvZyguLi5kYXRhKSk7XG4gICAgfVxuICB9LFxuICBjbGVhcjogKCkgPT4ge1xuICB9LFxuICBkZWJ1ZzogKC4uLmRhdGEpID0+IHtcbiAgICBzeXMuY29uc29sZV9sb2coY29uc29sZV9sZXZlbF9kZWJ1ZywgZm10TG9nKC4uLmRhdGEpKTtcbiAgfSxcbiAgZXJyb3I6ICguLi5kYXRhKSA9PiB7XG4gICAgc3lzLmNvbnNvbGVfbG9nKGNvbnNvbGVfbGV2ZWxfZXJyb3IsIGZtdExvZyguLi5kYXRhKSk7XG4gIH0sXG4gIGluZm86ICguLi5kYXRhKSA9PiB7XG4gICAgc3lzLmNvbnNvbGVfbG9nKGNvbnNvbGVfbGV2ZWxfaW5mbywgZm10TG9nKC4uLmRhdGEpKTtcbiAgfSxcbiAgbG9nOiAoLi4uZGF0YSkgPT4ge1xuICAgIHN5cy5jb25zb2xlX2xvZyhjb25zb2xlX2xldmVsX2luZm8sIGZtdExvZyguLi5kYXRhKSk7XG4gIH0sXG4gIHRhYmxlOiAodGFidWxhckRhdGEsIF9wcm9wZXJ0aWVzKSA9PiB7XG4gICAgc3lzLmNvbnNvbGVfbG9nKGNvbnNvbGVfbGV2ZWxfaW5mbywgZm10TG9nKHRhYnVsYXJEYXRhKSk7XG4gIH0sXG4gIHRyYWNlOiAoLi4uZGF0YSkgPT4ge1xuICAgIHN5cy5jb25zb2xlX2xvZyhjb25zb2xlX2xldmVsX3RyYWNlLCBmbXRMb2coLi4uZGF0YSkpO1xuICB9LFxuICB3YXJuOiAoLi4uZGF0YSkgPT4ge1xuICAgIHN5cy5jb25zb2xlX2xvZyhjb25zb2xlX2xldmVsX3dhcm4sIGZtdExvZyguLi5kYXRhKSk7XG4gIH0sXG4gIGRpcjogKF9pdGVtLCBfb3B0aW9ucykgPT4ge1xuICB9LFxuICBkaXJ4bWw6ICguLi5fZGF0YSkgPT4ge1xuICB9LFxuICAvLyBDb3VudGluZ1xuICBjb3VudDogKF9sYWJlbCA9IFwiZGVmYXVsdFwiKSA9PiB7XG4gIH0sXG4gIGNvdW50UmVzZXQ6IChfbGFiZWwgPSBcImRlZmF1bHRcIikgPT4ge1xuICB9LFxuICAvLyBHcm91cGluZ1xuICBncm91cDogKC4uLl9kYXRhKSA9PiB7XG4gIH0sXG4gIGdyb3VwQ29sbGFwc2VkOiAoLi4uX2RhdGEpID0+IHtcbiAgfSxcbiAgZ3JvdXBFbmQ6ICgpID0+IHtcbiAgfSxcbiAgLy8gVGltaW5nXG4gIHRpbWU6IChsYWJlbCA9IFwiZGVmYXVsdFwiKSA9PiB7XG4gICAgaWYgKHRpbWVyTWFwLmhhcyhsYWJlbCkpIHtcbiAgICAgIHN5cy5jb25zb2xlX2xvZyhjb25zb2xlX2xldmVsX3dhcm4sIGBUaW1lciAnJHtsYWJlbH0nIGFscmVhZHkgZXhpc3RzLmApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aW1lck1hcC5zZXQobGFiZWwsIHN5cy5jb25zb2xlX3RpbWVyX3N0YXJ0KGxhYmVsKSk7XG4gIH0sXG4gIHRpbWVMb2c6IChsYWJlbCA9IFwiZGVmYXVsdFwiLCAuLi5kYXRhKSA9PiB7XG4gICAgc3lzLmNvbnNvbGVfbG9nKGNvbnNvbGVfbGV2ZWxfaW5mbywgZm10TG9nKGxhYmVsLCAuLi5kYXRhKSk7XG4gIH0sXG4gIHRpbWVFbmQ6IChsYWJlbCA9IFwiZGVmYXVsdFwiKSA9PiB7XG4gICAgY29uc3Qgc3BhbklkID0gdGltZXJNYXAuZ2V0KGxhYmVsKTtcbiAgICBpZiAoc3BhbklkID09PSB2b2lkIDApIHtcbiAgICAgIHN5cy5jb25zb2xlX2xvZyhjb25zb2xlX2xldmVsX3dhcm4sIGBUaW1lciAnJHtsYWJlbH0nIGRvZXMgbm90IGV4aXN0LmApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBzeXMuY29uc29sZV90aW1lcl9lbmQoc3BhbklkKTtcbiAgICB0aW1lck1hcC5kZWxldGUobGFiZWwpO1xuICB9LFxuICAvLyBBZGRpdGlvbmFsIGNvbnNvbGUgbWV0aG9kcyB0byBzYXRpc2Z5IHRoZSBDb25zb2xlIGludGVyZmFjZVxuICB0aW1lU3RhbXA6ICgpID0+IHtcbiAgfSxcbiAgcHJvZmlsZTogKCkgPT4ge1xuICB9LFxuICBwcm9maWxlRW5kOiAoKSA9PiB7XG4gIH1cbn07XG5cbi8vIHNyYy9zZXJ2ZXIvcG9seWZpbGxzLnRzXG5nbG9iYWxUaGlzLmNvbnNvbGUgPSBjb25zb2xlMjtcbi8qISBCdW5kbGVkIGxpY2Vuc2UgaW5mb3JtYXRpb246XG5cbnN0YXR1c2VzL2luZGV4LmpzOlxuICAoKiFcbiAgICogc3RhdHVzZXNcbiAgICogQ29weXJpZ2h0KGMpIDIwMTQgSm9uYXRoYW4gT25nXG4gICAqIENvcHlyaWdodChjKSAyMDE2IERvdWdsYXMgQ2hyaXN0b3BoZXIgV2lsc29uXG4gICAqIE1JVCBMaWNlbnNlZFxuICAgKilcbiovXG5cbmV4cG9ydCB7IEFycmF5QnVpbGRlciwgQXJyYXlDb2x1bW5CdWlsZGVyLCBCb29sQnVpbGRlciwgQm9vbENvbHVtbkJ1aWxkZXIsIEJvb2xlYW5FeHByLCBCeXRlQXJyYXlCdWlsZGVyLCBCeXRlQXJyYXlDb2x1bW5CdWlsZGVyLCBDYXNlQ29udmVyc2lvblBvbGljeSwgQ29sdW1uQnVpbGRlciwgQ29sdW1uRXhwcmVzc2lvbiwgQ29ubmVjdGlvbklkQnVpbGRlciwgQ29ubmVjdGlvbklkQ29sdW1uQnVpbGRlciwgRjMyQnVpbGRlciwgRjMyQ29sdW1uQnVpbGRlciwgRjY0QnVpbGRlciwgRjY0Q29sdW1uQnVpbGRlciwgSTEyOEJ1aWxkZXIsIEkxMjhDb2x1bW5CdWlsZGVyLCBJMTZCdWlsZGVyLCBJMTZDb2x1bW5CdWlsZGVyLCBJMjU2QnVpbGRlciwgSTI1NkNvbHVtbkJ1aWxkZXIsIEkzMkJ1aWxkZXIsIEkzMkNvbHVtbkJ1aWxkZXIsIEk2NEJ1aWxkZXIsIEk2NENvbHVtbkJ1aWxkZXIsIEk4QnVpbGRlciwgSThDb2x1bW5CdWlsZGVyLCBJZGVudGl0eUJ1aWxkZXIsIElkZW50aXR5Q29sdW1uQnVpbGRlciwgT3B0aW9uQnVpbGRlciwgT3B0aW9uQ29sdW1uQnVpbGRlciwgUHJvZHVjdEJ1aWxkZXIsIFByb2R1Y3RDb2x1bW5CdWlsZGVyLCBSYW5nZSwgUmVmQnVpbGRlciwgUmVzdWx0QnVpbGRlciwgUmVzdWx0Q29sdW1uQnVpbGRlciwgUm93QnVpbGRlciwgU2NoZWR1bGVBdEJ1aWxkZXIsIFNjaGVkdWxlQXRDb2x1bW5CdWlsZGVyLCBTZW5kZXJFcnJvciwgU2ltcGxlU3VtQnVpbGRlciwgU2ltcGxlU3VtQ29sdW1uQnVpbGRlciwgU3BhY2V0aW1lSG9zdEVycm9yLCBTdHJpbmdCdWlsZGVyLCBTdHJpbmdDb2x1bW5CdWlsZGVyLCBTdW1CdWlsZGVyLCBTdW1Db2x1bW5CdWlsZGVyLCBUaW1lRHVyYXRpb25CdWlsZGVyLCBUaW1lRHVyYXRpb25Db2x1bW5CdWlsZGVyLCBUaW1lc3RhbXBCdWlsZGVyLCBUaW1lc3RhbXBDb2x1bW5CdWlsZGVyLCBUeXBlQnVpbGRlciwgVTEyOEJ1aWxkZXIsIFUxMjhDb2x1bW5CdWlsZGVyLCBVMTZCdWlsZGVyLCBVMTZDb2x1bW5CdWlsZGVyLCBVMjU2QnVpbGRlciwgVTI1NkNvbHVtbkJ1aWxkZXIsIFUzMkJ1aWxkZXIsIFUzMkNvbHVtbkJ1aWxkZXIsIFU2NEJ1aWxkZXIsIFU2NENvbHVtbkJ1aWxkZXIsIFU4QnVpbGRlciwgVThDb2x1bW5CdWlsZGVyLCBVdWlkQnVpbGRlciwgVXVpZENvbHVtbkJ1aWxkZXIsIGFuZCwgY3JlYXRlVGFibGVSZWZGcm9tRGVmLCBlcnJvcnMsIGV2YWx1YXRlQm9vbGVhbkV4cHIsIGdldFF1ZXJ5QWNjZXNzb3JOYW1lLCBnZXRRdWVyeVRhYmxlTmFtZSwgZ2V0UXVlcnlXaGVyZUNsYXVzZSwgaXNSb3dUeXBlZFF1ZXJ5LCBpc1R5cGVkUXVlcnksIGxpdGVyYWwsIG1ha2VRdWVyeUJ1aWxkZXIsIG5vdCwgb3IsIHNjaGVtYSwgdCwgdGFibGUsIHRvQ2FtZWxDYXNlLCB0b0NvbXBhcmFibGVWYWx1ZSwgdG9TcWwgfTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4Lm1qcy5tYXBcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4Lm1qcy5tYXAiLCJpbXBvcnQgeyBzY2hlbWEsIHQsIHRhYmxlLCBTZW5kZXJFcnJvciB9IGZyb20gJ3NwYWNldGltZWRiL3NlcnZlcic7XG5cbmNvbnN0IGNoYW5uZWxfa2luZCA9IHQuZW51bSgnQ2hhbm5lbEtpbmQnLCB7IHRleHQ6IHQudW5pdCgpLCB2b2ljZTogdC51bml0KCkgfSk7XG5cbmNvbnN0IHVzZXIgPSB0YWJsZShcbiAge1xuICAgIG5hbWU6ICd1c2VyJyxcbiAgICBwdWJsaWM6IHRydWUsXG4gIH0sXG4gIHtcbiAgICBpZGVudGl0eTogdC5pZGVudGl0eSgpLnByaW1hcnlLZXkoKSxcbiAgICBuYW1lOiB0LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgb25saW5lOiB0LmJvb2woKSxcbiAgICBpc3N1ZXI6IHQuc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgICBzdWJqZWN0OiB0LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgdXNlcm5hbWU6IHQuc3RyaW5nKCkub3B0aW9uYWwoKSwgLy8gRm9yIGNyZWRzLWJhc2VkIGF1dGhcbiAgICBwYXNzd29yZDogdC5zdHJpbmcoKS5vcHRpb25hbCgpLCAvLyBGb3IgY3JlZHMtYmFzZWQgYXV0aCAoTm90ZTogcGxhaW4gdGV4dCBmb3IgTVZQKVxuICB9XG4pO1xuXG5jb25zdCBzZXJ2ZXIgPSB0YWJsZShcbiAgeyBuYW1lOiAnc2VydmVyJywgcHVibGljOiB0cnVlIH0sXG4gIHtcbiAgICBpZDogdC51NjQoKS5wcmltYXJ5S2V5KCkuYXV0b0luYygpLFxuICAgIG5hbWU6IHQuc3RyaW5nKCksXG4gICAgb3duZXI6IHQuaWRlbnRpdHkoKS5vcHRpb25hbCgpLFxuICB9XG4pO1xuXG5jb25zdCBjaGFubmVsID0gdGFibGUoXG4gIHtcbiAgICBuYW1lOiAnY2hhbm5lbCcsXG4gICAgcHVibGljOiB0cnVlLFxuICAgIGluZGV4ZXM6IFtcbiAgICAgIHsgYWNjZXNzb3I6ICdieV9zZXJ2ZXJfaWQnLCBhbGdvcml0aG06ICdidHJlZScsIGNvbHVtbnM6IFsnc2VydmVyX2lkJ10gfVxuICAgIF1cbiAgfSxcbiAge1xuICAgIGlkOiB0LnU2NCgpLnByaW1hcnlLZXkoKS5hdXRvSW5jKCksXG4gICAgc2VydmVyX2lkOiB0LnU2NCgpLFxuICAgIG5hbWU6IHQuc3RyaW5nKCksXG4gICAga2luZDogY2hhbm5lbF9raW5kLFxuICB9XG4pO1xuXG5jb25zdCB2b2ljZV9zdGF0ZSA9IHRhYmxlKFxuICB7XG4gICAgbmFtZTogJ3ZvaWNlX3N0YXRlJyxcbiAgICBwdWJsaWM6IHRydWUsXG4gICAgaW5kZXhlczogW1xuICAgICAgeyBhY2Nlc3NvcjogJ2J5X2NoYW5uZWxfaWQnLCBhbGdvcml0aG06ICdidHJlZScsIGNvbHVtbnM6IFsnY2hhbm5lbF9pZCddIH1cbiAgICBdXG4gIH0sXG4gIHtcbiAgICBpZGVudGl0eTogdC5pZGVudGl0eSgpLnByaW1hcnlLZXkoKSxcbiAgICBjaGFubmVsX2lkOiB0LnU2NCgpLFxuICB9XG4pO1xuXG5jb25zdCBzZHBfb2ZmZXIgPSB0YWJsZShcbiAge1xuICAgIG5hbWU6ICdzZHBfb2ZmZXInLFxuICAgIHB1YmxpYzogdHJ1ZSxcbiAgICBpbmRleGVzOiBbXG4gICAgICB7IGFjY2Vzc29yOiAnYnlfcmVjZWl2ZXInLCBhbGdvcml0aG06ICdidHJlZScsIGNvbHVtbnM6IFsncmVjZWl2ZXInXSB9XG4gICAgXVxuICB9LFxuICB7XG4gICAgc2VuZGVyOiB0LmlkZW50aXR5KCksXG4gICAgcmVjZWl2ZXI6IHQuaWRlbnRpdHkoKSxcbiAgICBzZHA6IHQuc3RyaW5nKCksXG4gICAgY2hhbm5lbF9pZDogdC51NjQoKSxcbiAgfVxuKTtcblxuY29uc3Qgc2RwX2Fuc3dlciA9IHRhYmxlKFxuICB7XG4gICAgbmFtZTogJ3NkcF9hbnN3ZXInLFxuICAgIHB1YmxpYzogdHJ1ZSxcbiAgICBpbmRleGVzOiBbXG4gICAgICB7IGFjY2Vzc29yOiAnYnlfcmVjZWl2ZXInLCBhbGdvcml0aG06ICdidHJlZScsIGNvbHVtbnM6IFsncmVjZWl2ZXInXSB9XG4gICAgXVxuICB9LFxuICB7XG4gICAgc2VuZGVyOiB0LmlkZW50aXR5KCksXG4gICAgcmVjZWl2ZXI6IHQuaWRlbnRpdHkoKSxcbiAgICBzZHA6IHQuc3RyaW5nKCksXG4gICAgY2hhbm5lbF9pZDogdC51NjQoKSxcbiAgfVxuKTtcblxuY29uc3QgaWNlX2NhbmRpZGF0ZSA9IHRhYmxlKFxuICB7XG4gICAgbmFtZTogJ2ljZV9jYW5kaWRhdGUnLFxuICAgIHB1YmxpYzogdHJ1ZSxcbiAgICBpbmRleGVzOiBbXG4gICAgICB7IGFjY2Vzc29yOiAnYnlfcmVjZWl2ZXInLCBhbGdvcml0aG06ICdidHJlZScsIGNvbHVtbnM6IFsncmVjZWl2ZXInXSB9XG4gICAgXVxuICB9LFxuICB7XG4gICAgc2VuZGVyOiB0LmlkZW50aXR5KCksXG4gICAgcmVjZWl2ZXI6IHQuaWRlbnRpdHkoKSxcbiAgICBjYW5kaWRhdGU6IHQuc3RyaW5nKCksXG4gICAgY2hhbm5lbF9pZDogdC51NjQoKSxcbiAgfVxuKTtcblxuY29uc3QgdGhyZWFkID0gdGFibGUoXG4gIHtcbiAgICBuYW1lOiAndGhyZWFkJyxcbiAgICBwdWJsaWM6IHRydWUsXG4gICAgaW5kZXhlczogW1xuICAgICAgeyBhY2Nlc3NvcjogJ2J5X2NoYW5uZWxfaWQnLCBhbGdvcml0aG06ICdidHJlZScsIGNvbHVtbnM6IFsnY2hhbm5lbF9pZCddIH1cbiAgICBdXG4gIH0sXG4gIHtcbiAgICBpZDogdC51NjQoKS5wcmltYXJ5S2V5KCkuYXV0b0luYygpLFxuICAgIGNoYW5uZWxfaWQ6IHQudTY0KCksXG4gICAgcGFyZW50X21lc3NhZ2VfaWQ6IHQudTY0KCkudW5pcXVlKCksXG4gICAgbmFtZTogdC5zdHJpbmcoKSxcbiAgfVxuKTtcblxuY29uc3QgbWVzc2FnZSA9IHRhYmxlKFxuICB7XG4gICAgbmFtZTogJ21lc3NhZ2UnLFxuICAgIHB1YmxpYzogdHJ1ZSxcbiAgICBpbmRleGVzOiBbXG4gICAgICB7IGFjY2Vzc29yOiAnYnlfY2hhbm5lbF9pZCcsIGFsZ29yaXRobTogJ2J0cmVlJywgY29sdW1uczogWydjaGFubmVsX2lkJ10gfSxcbiAgICAgIHsgYWNjZXNzb3I6ICdieV90aHJlYWRfaWQnLCBhbGdvcml0aG06ICdidHJlZScsIGNvbHVtbnM6IFsndGhyZWFkX2lkJ10gfVxuICAgIF1cbiAgfSxcbiAge1xuICAgIGlkOiB0LnU2NCgpLnByaW1hcnlLZXkoKS5hdXRvSW5jKCksXG4gICAgc2VuZGVyOiB0LmlkZW50aXR5KCksXG4gICAgc2VudDogdC50aW1lc3RhbXAoKSxcbiAgICB0ZXh0OiB0LnN0cmluZygpLFxuICAgIGNoYW5uZWxfaWQ6IHQudTY0KCksXG4gICAgdGhyZWFkX2lkOiB0LnU2NCgpLm9wdGlvbmFsKCksXG4gIH1cbik7XG5cbmNvbnN0IHNwYWNldGltZWRiID0gc2NoZW1hKHsgdXNlciwgc2VydmVyLCBjaGFubmVsLCB2b2ljZV9zdGF0ZSwgc2RwX29mZmVyLCBzZHBfYW5zd2VyLCBpY2VfY2FuZGlkYXRlLCB0aHJlYWQsIG1lc3NhZ2UgfSk7XG5leHBvcnQgZGVmYXVsdCBzcGFjZXRpbWVkYjtcblxuZnVuY3Rpb24gdmFsaWRhdGVOYW1lKG5hbWU6IHN0cmluZykge1xuICBpZiAoIW5hbWUgfHwgbmFtZS50cmltKCkubGVuZ3RoID09PSAwKSB0aHJvdyBuZXcgU2VuZGVyRXJyb3IoJ05hbWVzIG11c3Qgbm90IGJlIGVtcHR5Jyk7XG59XG5cbmV4cG9ydCBjb25zdCBzZXRfbmFtZSA9IHNwYWNldGltZWRiLnJlZHVjZXIoXG4gIHsgbmFtZTogdC5zdHJpbmcoKSB9LFxuICAoY3R4LCB7IG5hbWUgfSkgPT4ge1xuICAgIHZhbGlkYXRlTmFtZShuYW1lKTtcbiAgICBjb25zdCB1c2VyID0gY3R4LmRiLnVzZXIuaWRlbnRpdHkuZmluZChjdHguc2VuZGVyKTtcbiAgICBpZiAoIXVzZXIpIHRocm93IG5ldyBTZW5kZXJFcnJvcignQ2Fubm90IHNldCBuYW1lIGZvciB1bmtub3duIHVzZXInKTtcbiAgICBjdHguZGIudXNlci5pZGVudGl0eS51cGRhdGUoeyAuLi51c2VyLCBuYW1lIH0pO1xuICB9XG4pO1xuXG5leHBvcnQgY29uc3QgcmVnaXN0ZXIgPSBzcGFjZXRpbWVkYi5yZWR1Y2VyKFxuICB7IHVzZXJuYW1lOiB0LnN0cmluZygpLCBwYXNzd29yZDogdC5zdHJpbmcoKSB9LFxuICAoY3R4LCB7IHVzZXJuYW1lLCBwYXNzd29yZCB9KSA9PiB7XG4gICAgdmFsaWRhdGVOYW1lKHVzZXJuYW1lKTtcbiAgICBpZiAoIXBhc3N3b3JkIHx8IHBhc3N3b3JkLmxlbmd0aCA8IDQpIHRocm93IG5ldyBTZW5kZXJFcnJvcignUGFzc3dvcmQgbXVzdCBiZSBhdCBsZWFzdCA0IGNoYXJhY3RlcnMnKTtcbiAgICBcbiAgICBmb3IgKGNvbnN0IHUgb2YgY3R4LmRiLnVzZXIuaXRlcigpKSB7XG4gICAgICBpZiAodS51c2VybmFtZSA9PT0gdXNlcm5hbWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IFNlbmRlckVycm9yKCdVc2VybmFtZSBhbHJlYWR5IHRha2VuJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgdXNlciA9IGN0eC5kYi51c2VyLmlkZW50aXR5LmZpbmQoY3R4LnNlbmRlcik7XG4gICAgaWYgKHVzZXIpIHtcbiAgICAgIGN0eC5kYi51c2VyLmlkZW50aXR5LnVwZGF0ZSh7IFxuICAgICAgICAuLi51c2VyLCBcbiAgICAgICAgdXNlcm5hbWUsIFxuICAgICAgICBwYXNzd29yZCxcbiAgICAgICAgbmFtZTogdXNlci5uYW1lIHx8IHVzZXJuYW1lIFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN0eC5kYi51c2VyLmluc2VydCh7XG4gICAgICAgIGlkZW50aXR5OiBjdHguc2VuZGVyLFxuICAgICAgICB1c2VybmFtZSxcbiAgICAgICAgcGFzc3dvcmQsXG4gICAgICAgIG5hbWU6IHVzZXJuYW1lLFxuICAgICAgICBvbmxpbmU6IHRydWUsXG4gICAgICAgIGlzc3VlcjogdW5kZWZpbmVkLFxuICAgICAgICBzdWJqZWN0OiB1bmRlZmluZWRcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuKTtcblxuZXhwb3J0IGNvbnN0IGxvZ2luID0gc3BhY2V0aW1lZGIucmVkdWNlcihcbiAgeyB1c2VybmFtZTogdC5zdHJpbmcoKSwgcGFzc3dvcmQ6IHQuc3RyaW5nKCkgfSxcbiAgKGN0eCwgeyB1c2VybmFtZSwgcGFzc3dvcmQgfSkgPT4ge1xuICAgIGxldCBmb3VuZFVzZXIgPSBudWxsO1xuICAgIGZvciAoY29uc3QgdSBvZiBjdHguZGIudXNlci5pdGVyKCkpIHtcbiAgICAgIGlmICh1LnVzZXJuYW1lID09PSB1c2VybmFtZSAmJiB1LnBhc3N3b3JkID09PSBwYXNzd29yZCkge1xuICAgICAgICBmb3VuZFVzZXIgPSB1O1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWZvdW5kVXNlcikge1xuICAgICAgdGhyb3cgbmV3IFNlbmRlckVycm9yKCdJbnZhbGlkIHVzZXJuYW1lIG9yIHBhc3N3b3JkJyk7XG4gICAgfVxuXG4gICAgY29uc3QgY3VycmVudElkZW50aXR5VXNlciA9IGN0eC5kYi51c2VyLmlkZW50aXR5LmZpbmQoY3R4LnNlbmRlcik7XG4gICAgaWYgKGN1cnJlbnRJZGVudGl0eVVzZXIgJiYgY3VycmVudElkZW50aXR5VXNlci5pZGVudGl0eS50b0hleFN0cmluZygpICE9PSBmb3VuZFVzZXIuaWRlbnRpdHkudG9IZXhTdHJpbmcoKSkge1xuICAgICAgIGN0eC5kYi51c2VyLmlkZW50aXR5LmRlbGV0ZShjdHguc2VuZGVyKTtcbiAgICB9XG5cbiAgICBpZiAoZm91bmRVc2VyLmlkZW50aXR5LnRvSGV4U3RyaW5nKCkgIT09IGN0eC5zZW5kZXIudG9IZXhTdHJpbmcoKSkge1xuICAgICAgY3R4LmRiLnVzZXIuaWRlbnRpdHkuZGVsZXRlKGZvdW5kVXNlci5pZGVudGl0eSk7XG4gICAgICBjdHguZGIudXNlci5pbnNlcnQoe1xuICAgICAgICAuLi5mb3VuZFVzZXIsXG4gICAgICAgIGlkZW50aXR5OiBjdHguc2VuZGVyLFxuICAgICAgICBvbmxpbmU6IHRydWVcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBjdHguZGIudXNlci5pZGVudGl0eS51cGRhdGUoe1xuICAgICAgICAuLi5mb3VuZFVzZXIsXG4gICAgICAgIG9ubGluZTogdHJ1ZVxuICAgICAgfSk7XG4gICAgfVxuICB9XG4pO1xuXG5leHBvcnQgY29uc3QgY3JlYXRlX3NlcnZlciA9IHNwYWNldGltZWRiLnJlZHVjZXIoXG4gIHsgbmFtZTogdC5zdHJpbmcoKSB9LFxuICAoY3R4LCB7IG5hbWUgfSkgPT4ge1xuICAgIHZhbGlkYXRlTmFtZShuYW1lKTtcbiAgICBjb25zdCB1c2VyID0gY3R4LmRiLnVzZXIuaWRlbnRpdHkuZmluZChjdHguc2VuZGVyKTtcbiAgICBpZiAoIXVzZXIgfHwgKCF1c2VyLnVzZXJuYW1lICYmICF1c2VyLnN1YmplY3QpKSB7XG4gICAgICB0aHJvdyBuZXcgU2VuZGVyRXJyb3IoJ1lvdSBtdXN0IGJlIGxvZ2dlZCBpbiB0byBjcmVhdGUgYSBzZXJ2ZXInKTtcbiAgICB9XG4gICAgY29uc3QgcyA9IGN0eC5kYi5zZXJ2ZXIuaW5zZXJ0KHsgaWQ6IDBuLCBuYW1lLCBvd25lcjogY3R4LnNlbmRlciB9KTtcbiAgICBjdHguZGIuY2hhbm5lbC5pbnNlcnQoeyBpZDogMG4sIHNlcnZlcl9pZDogcy5pZCwgbmFtZTogJ2dlbmVyYWwnLCBraW5kOiB7IHRhZzogJ3RleHQnIH0gfSk7XG4gICAgY3R4LmRiLmNoYW5uZWwuaW5zZXJ0KHsgaWQ6IDBuLCBzZXJ2ZXJfaWQ6IHMuaWQsIG5hbWU6ICdWb2ljZSBHZW5lcmFsJywga2luZDogeyB0YWc6ICd2b2ljZScgfSB9KTtcbiAgfVxuKTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZV9jaGFubmVsID0gc3BhY2V0aW1lZGIucmVkdWNlcihcbiAgeyBuYW1lOiB0LnN0cmluZygpLCBzZXJ2ZXJJZDogdC51NjQoKSwgaXNWb2ljZTogdC5ib29sKCkgfSxcbiAgKGN0eCwgeyBuYW1lLCBzZXJ2ZXJJZCwgaXNWb2ljZSB9KSA9PiB7XG4gICAgdmFsaWRhdGVOYW1lKG5hbWUpO1xuICAgIGNvbnN0IHVzZXIgPSBjdHguZGIudXNlci5pZGVudGl0eS5maW5kKGN0eC5zZW5kZXIpO1xuICAgIGlmICghdXNlciB8fCAoIXVzZXIudXNlcm5hbWUgJiYgIXVzZXIuc3ViamVjdCkpIHtcbiAgICAgIHRocm93IG5ldyBTZW5kZXJFcnJvcignWW91IG11c3QgYmUgbG9nZ2VkIGluIHRvIGNyZWF0ZSBhIGNoYW5uZWwnKTtcbiAgICB9XG4gICAgY29uc3QgcyA9IGN0eC5kYi5zZXJ2ZXIuaWQuZmluZChzZXJ2ZXJJZCk7XG4gICAgaWYgKCFzKSB0aHJvdyBuZXcgU2VuZGVyRXJyb3IoJ1NlcnZlciBub3QgZm91bmQnKTtcbiAgICBjdHguZGIuY2hhbm5lbC5pbnNlcnQoeyBcbiAgICAgIGlkOiAwbiwgXG4gICAgICBzZXJ2ZXJfaWQ6IHNlcnZlcklkLCBcbiAgICAgIG5hbWUsIFxuICAgICAga2luZDogaXNWb2ljZSA/IHsgdGFnOiAndm9pY2UnIH0gOiB7IHRhZzogJ3RleHQnIH0gXG4gICAgfSk7XG4gIH1cbik7XG5cbmV4cG9ydCBjb25zdCBqb2luX3ZvaWNlID0gc3BhY2V0aW1lZGIucmVkdWNlcihcbiAgeyBjaGFubmVsSWQ6IHQudTY0KCkgfSxcbiAgKGN0eCwgeyBjaGFubmVsSWQgfSkgPT4ge1xuICAgIGNvbnN0IHVzZXIgPSBjdHguZGIudXNlci5pZGVudGl0eS5maW5kKGN0eC5zZW5kZXIpO1xuICAgIGlmICghdXNlciB8fCAoIXVzZXIudXNlcm5hbWUgJiYgIXVzZXIuc3ViamVjdCkpIHtcbiAgICAgIHRocm93IG5ldyBTZW5kZXJFcnJvcignWW91IG11c3QgYmUgbG9nZ2VkIGluIHRvIGpvaW4gdm9pY2UnKTtcbiAgICB9XG4gICAgY29uc3QgY2hhbiA9IGN0eC5kYi5jaGFubmVsLmlkLmZpbmQoY2hhbm5lbElkKTtcbiAgICBpZiAoIWNoYW4gfHwgY2hhbi5raW5kLnRhZyAhPT0gJ3ZvaWNlJykgdGhyb3cgbmV3IFNlbmRlckVycm9yKCdJbnZhbGlkIHZvaWNlIGNoYW5uZWwnKTtcbiAgICBcbiAgICBjb25zdCBleGlzdGluZyA9IGN0eC5kYi52b2ljZV9zdGF0ZS5pZGVudGl0eS5maW5kKGN0eC5zZW5kZXIpO1xuICAgIGlmIChleGlzdGluZykge1xuICAgICAgaWYgKGV4aXN0aW5nLmNoYW5uZWxfaWQgIT09IGNoYW5uZWxJZCkge1xuICAgICAgICBjbGVhclNpZ25hbGluZ0ZvclVzZXIoY3R4LCBjdHguc2VuZGVyKTtcbiAgICAgICAgY3R4LmRiLnZvaWNlX3N0YXRlLmlkZW50aXR5LnVwZGF0ZSh7IGlkZW50aXR5OiBjdHguc2VuZGVyLCBjaGFubmVsX2lkOiBjaGFubmVsSWQgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGN0eC5kYi52b2ljZV9zdGF0ZS5pbnNlcnQoeyBpZGVudGl0eTogY3R4LnNlbmRlciwgY2hhbm5lbF9pZDogY2hhbm5lbElkIH0pO1xuICAgIH1cbiAgfVxuKTtcblxuZXhwb3J0IGNvbnN0IGxlYXZlX3ZvaWNlID0gc3BhY2V0aW1lZGIucmVkdWNlcigoY3R4KSA9PiB7XG4gIGN0eC5kYi52b2ljZV9zdGF0ZS5pZGVudGl0eS5kZWxldGUoY3R4LnNlbmRlcik7XG4gIGNsZWFyU2lnbmFsaW5nRm9yVXNlcihjdHgsIGN0eC5zZW5kZXIpO1xufSk7XG5cbmV4cG9ydCBjb25zdCBzZW5kX3NkcF9vZmZlciA9IHNwYWNldGltZWRiLnJlZHVjZXIoXG4gIHsgcmVjZWl2ZXI6IHQuaWRlbnRpdHkoKSwgc2RwOiB0LnN0cmluZygpLCBjaGFubmVsSWQ6IHQudTY0KCkgfSxcbiAgKGN0eCwgeyByZWNlaXZlciwgc2RwLCBjaGFubmVsSWQgfSkgPT4ge1xuICAgIGN0eC5kYi5zZHBfb2ZmZXIuaW5zZXJ0KHsgc2VuZGVyOiBjdHguc2VuZGVyLCByZWNlaXZlciwgc2RwLCBjaGFubmVsX2lkOiBjaGFubmVsSWQgfSk7XG4gIH1cbik7XG5cbmV4cG9ydCBjb25zdCBzZW5kX3NkcF9hbnN3ZXIgPSBzcGFjZXRpbWVkYi5yZWR1Y2VyKFxuICB7IHJlY2VpdmVyOiB0LmlkZW50aXR5KCksIHNkcDogdC5zdHJpbmcoKSwgY2hhbm5lbElkOiB0LnU2NCgpIH0sXG4gIChjdHgsIHsgcmVjZWl2ZXIsIHNkcCwgY2hhbm5lbElkIH0pID0+IHtcbiAgICBjdHguZGIuc2RwX2Fuc3dlci5pbnNlcnQoeyBzZW5kZXI6IGN0eC5zZW5kZXIsIHJlY2VpdmVyLCBzZHAsIGNoYW5uZWxfaWQ6IGNoYW5uZWxJZCB9KTtcbiAgfVxuKTtcblxuZXhwb3J0IGNvbnN0IHNlbmRfaWNlX2NhbmRpZGF0ZSA9IHNwYWNldGltZWRiLnJlZHVjZXIoXG4gIHsgcmVjZWl2ZXI6IHQuaWRlbnRpdHkoKSwgY2FuZGlkYXRlOiB0LnN0cmluZygpLCBjaGFubmVsSWQ6IHQudTY0KCkgfSxcbiAgKGN0eCwgeyByZWNlaXZlciwgY2FuZGlkYXRlLCBjaGFubmVsSWQgfSkgPT4ge1xuICAgIGN0eC5kYi5pY2VfY2FuZGlkYXRlLmluc2VydCh7IHNlbmRlcjogY3R4LnNlbmRlciwgcmVjZWl2ZXIsIGNhbmRpZGF0ZSwgY2hhbm5lbF9pZDogY2hhbm5lbElkIH0pO1xuICB9XG4pO1xuXG5mdW5jdGlvbiBjbGVhclNpZ25hbGluZ0ZvclVzZXIoY3R4OiBhbnksIGlkZW50aXR5OiBhbnkpIHtcbiAgLy8gQ2xlYW4gdXAgc3RhbGUgc2lnbmFsaW5nIG1lc3NhZ2VzIGZvciB0aGUgdXNlclxuICAvLyBOb3RlOiBJdGVyYXRpbmcgYW5kIGRlbGV0aW5nIG1pZ2h0IG5vdCBiZSB0aGUgbW9zdCBwZXJmb3JtYW50IGZvciBsYXJnZSB0YWJsZXMuXG4gIC8vIEluIGEgcHJvZHVjdGlvbiBzY2VuYXJpbywgY29uc2lkZXIgVFRMcyBvciBtb3JlIHRhcmdldGVkIGRlbGV0aW9uIHN0cmF0ZWdpZXMuXG5cbiAgY29uc3QgdXNlck9mZmVycyA9IGN0eC5kYi5zZHBfb2ZmZXIuaXRlcigpLmZpbHRlcigob2ZmZXI6IGFueSkgPT4gXG4gICAgb2ZmZXIuc2VuZGVyLmlzRXF1YWwoaWRlbnRpdHkpIHx8IG9mZmVyLnJlY2VpdmVyLmlzRXF1YWwoaWRlbnRpdHkpXG4gICk7XG4gIGZvciAoY29uc3Qgb2ZmZXIgb2YgdXNlck9mZmVycykge1xuICAgIGN0eC5kYi5zZHBfb2ZmZXIuZGVsZXRlKG9mZmVyLmlkKTsgLy8gQXNzdW1pbmcgJ2lkJyBpcyB0aGUgcHJpbWFyeSBrZXlcbiAgfVxuXG4gIGNvbnN0IHVzZXJBbnN3ZXJzID0gY3R4LmRiLnNkcF9hbnN3ZXIuaXRlcigpLmZpbHRlcigoYW5zd2VyOiBhbnkpID0+IFxuICAgIGFuc3dlci5zZW5kZXIuaXNFcXVhbChpZGVudGl0eSkgfHwgYW5zd2VyLnJlY2VpdmVyLmlzRXF1YWwoaWRlbnRpdHkpXG4gICk7XG4gIGZvciAoY29uc3QgYW5zd2VyIG9mIHVzZXJBbnN3ZXJzKSB7XG4gICAgY3R4LmRiLnNkcF9hbnN3ZXIuZGVsZXRlKGFuc3dlci5pZCk7IC8vIEFzc3VtaW5nICdpZCcgaXMgdGhlIHByaW1hcnkga2V5XG4gIH1cblxuICBjb25zdCB1c2VyQ2FuZGlkYXRlcyA9IGN0eC5kYi5pY2VfY2FuZGlkYXRlLml0ZXIoKS5maWx0ZXIoKGNhbmRpZGF0ZTogYW55KSA9PiBcbiAgICBjYW5kaWRhdGUuc2VuZGVyLmlzRXF1YWwoaWRlbnRpdHkpIHx8IGNhbmRpZGF0ZS5yZWNlaXZlci5pc0VxdWFsKGlkZW50aXR5KVxuICApO1xuICBmb3IgKGNvbnN0IGNhbmRpZGF0ZSBvZiB1c2VyQ2FuZGlkYXRlcykge1xuICAgIGN0eC5kYi5pY2VfY2FuZGlkYXRlLmRlbGV0ZShjYW5kaWRhdGUuaWQpOyAvLyBBc3N1bWluZyAnaWQnIGlzIHRoZSBwcmltYXJ5IGtleVxuICB9XG59XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVfdGhyZWFkID0gc3BhY2V0aW1lZGIucmVkdWNlcihcbiAgeyBuYW1lOiB0LnN0cmluZygpLCBjaGFubmVsSWQ6IHQudTY0KCksIHBhcmVudE1lc3NhZ2VJZDogdC51NjQoKSB9LFxuICAoY3R4LCB7IG5hbWUsIGNoYW5uZWxJZCwgcGFyZW50TWVzc2FnZUlkIH0pID0+IHtcbiAgICB2YWxpZGF0ZU5hbWUobmFtZSk7XG4gICAgY29uc3QgdXNlciA9IGN0eC5kYi51c2VyLmlkZW50aXR5LmZpbmQoY3R4LnNlbmRlcik7XG4gICAgaWYgKCF1c2VyIHx8ICghdXNlci51c2VybmFtZSAmJiAhdXNlci5zdWJqZWN0KSkge1xuICAgICAgdGhyb3cgbmV3IFNlbmRlckVycm9yKCdZb3UgbXVzdCBiZSBsb2dnZWQgaW4gdG8gY3JlYXRlIGEgdGhyZWFkJyk7XG4gICAgfVxuICAgIGNvbnN0IHBhcmVudE1zZyA9IGN0eC5kYi5tZXNzYWdlLmlkLmZpbmQocGFyZW50TWVzc2FnZUlkKTtcbiAgICBpZiAoIXBhcmVudE1zZykgdGhyb3cgbmV3IFNlbmRlckVycm9yKCdQYXJlbnQgbWVzc2FnZSBub3QgZm91bmQnKTtcbiAgICBcbiAgICBjdHguZGIudGhyZWFkLmluc2VydCh7IGlkOiAwbiwgY2hhbm5lbF9pZDogY2hhbm5lbElkLCBwYXJlbnRfbWVzc2FnZV9pZDogcGFyZW50TWVzc2FnZUlkLCBuYW1lIH0pO1xuICB9XG4pO1xuXG5leHBvcnQgY29uc3Qgc2VuZF9tZXNzYWdlID0gc3BhY2V0aW1lZGIucmVkdWNlcihcbiAgeyB0ZXh0OiB0LnN0cmluZygpLCBjaGFubmVsSWQ6IHQudTY0KCksIHRocmVhZElkOiB0LnU2NCgpLm9wdGlvbmFsKCkgfSxcbiAgKGN0eCwgeyB0ZXh0LCBjaGFubmVsSWQsIHRocmVhZElkIH0pID0+IHtcbiAgICBpZiAoIXRleHQgfHwgdGV4dC50cmltKCkubGVuZ3RoID09PSAwKSB0aHJvdyBuZXcgU2VuZGVyRXJyb3IoJ01lc3NhZ2VzIG11c3Qgbm90IGJlIGVtcHR5Jyk7XG4gICAgXG4gICAgY29uc3QgdXNlciA9IGN0eC5kYi51c2VyLmlkZW50aXR5LmZpbmQoY3R4LnNlbmRlcik7XG4gICAgaWYgKCF1c2VyIHx8ICghdXNlci51c2VybmFtZSAmJiAhdXNlci5zdWJqZWN0KSkge1xuICAgICAgdGhyb3cgbmV3IFNlbmRlckVycm9yKCdZb3UgbXVzdCBiZSBsb2dnZWQgaW4gdG8gc2VuZCBtZXNzYWdlcycpO1xuICAgIH1cblxuICAgIGN0eC5kYi5tZXNzYWdlLmluc2VydCh7XG4gICAgICBpZDogMG4sXG4gICAgICBzZW5kZXI6IGN0eC5zZW5kZXIsXG4gICAgICB0ZXh0LFxuICAgICAgc2VudDogY3R4LnRpbWVzdGFtcCxcbiAgICAgIGNoYW5uZWxfaWQ6IGNoYW5uZWxJZCxcbiAgICAgIHRocmVhZF9pZDogdGhyZWFkSWQsXG4gICAgfSk7XG4gIH1cbik7XG5cbmV4cG9ydCBjb25zdCBpbml0ID0gc3BhY2V0aW1lZGIuaW5pdChjdHggPT4ge1xuICBsZXQgaGFzU2VydmVycyA9IGZhbHNlO1xuICBmb3IgKGNvbnN0IF8gb2YgY3R4LmRiLnNlcnZlci5pdGVyKCkpIHtcbiAgICBoYXNTZXJ2ZXJzID0gdHJ1ZTtcbiAgICBicmVhaztcbiAgfVxuICBpZiAoIWhhc1NlcnZlcnMpIHtcbiAgICBjb25zdCBzID0gY3R4LmRiLnNlcnZlci5pbnNlcnQoeyBpZDogMG4sIG5hbWU6ICdTcGFjZXRpbWUgQ29tbXVuaXR5Jywgb3duZXI6IHVuZGVmaW5lZCB9KTtcbiAgICBjdHguZGIuY2hhbm5lbC5pbnNlcnQoeyBpZDogMG4sIHNlcnZlcl9pZDogcy5pZCwgbmFtZTogJ2dlbmVyYWwnLCBraW5kOiB7IHRhZzogJ3RleHQnIH0gfSk7XG4gICAgY3R4LmRiLmNoYW5uZWwuaW5zZXJ0KHsgaWQ6IDBuLCBzZXJ2ZXJfaWQ6IHMuaWQsIG5hbWU6ICdWb2ljZSBHZW5lcmFsJywga2luZDogeyB0YWc6ICd2b2ljZScgfSB9KTtcbiAgfVxufSk7XG5cbmV4cG9ydCBjb25zdCBvbkNvbm5lY3QgPSBzcGFjZXRpbWVkYi5jbGllbnRDb25uZWN0ZWQoY3R4ID0+IHtcbiAgY29uc3QgdXNlciA9IGN0eC5kYi51c2VyLmlkZW50aXR5LmZpbmQoY3R4LnNlbmRlcik7XG4gIFxuICBpZiAoY3R4LnNlbmRlckF1dGguaGFzSldUICYmIGN0eC5zZW5kZXJBdXRoLmp3dCkge1xuICAgIGNvbnN0IGp3dCA9IGN0eC5zZW5kZXJBdXRoLmp3dDtcbiAgICBjb25zdCBpc3N1ZXIgPSBqd3QuaXNzdWVyO1xuICAgIGNvbnN0IHN1YmplY3QgPSBqd3Quc3ViamVjdDtcbiAgICBjb25zdCBwYXlsb2FkID0gand0LmZ1bGxQYXlsb2FkO1xuICAgIGNvbnN0IG5hbWUgPSAocGF5bG9hZC5uYW1lIGFzIHN0cmluZykgfHwgKHBheWxvYWQubmlja25hbWUgYXMgc3RyaW5nKSB8fCAocGF5bG9hZC5wcmVmZXJyZWRfdXNlcm5hbWUgYXMgc3RyaW5nKSB8fCAocGF5bG9hZC5lbWFpbCBhcyBzdHJpbmcpO1xuXG4gICAgaWYgKHVzZXIpIHtcbiAgICAgIGN0eC5kYi51c2VyLmlkZW50aXR5LnVwZGF0ZSh7IFxuICAgICAgICAuLi51c2VyLCBcbiAgICAgICAgb25saW5lOiB0cnVlLFxuICAgICAgICBuYW1lOiB1c2VyLm5hbWUgfHwgbmFtZSxcbiAgICAgICAgaXNzdWVyLFxuICAgICAgICBzdWJqZWN0XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY3R4LmRiLnVzZXIuaW5zZXJ0KHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgaWRlbnRpdHk6IGN0eC5zZW5kZXIsXG4gICAgICAgIG9ubGluZTogdHJ1ZSxcbiAgICAgICAgaXNzdWVyLFxuICAgICAgICBzdWJqZWN0LFxuICAgICAgICB1c2VybmFtZTogdW5kZWZpbmVkLFxuICAgICAgICBwYXNzd29yZDogdW5kZWZpbmVkXG4gICAgICB9KTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodXNlcikge1xuICAgIGN0eC5kYi51c2VyLmlkZW50aXR5LnVwZGF0ZSh7IC4uLnVzZXIsIG9ubGluZTogdHJ1ZSB9KTtcbiAgfVxufSk7XG5cbmV4cG9ydCBjb25zdCBvbkRpc2Nvbm5lY3QgPSBzcGFjZXRpbWVkYi5jbGllbnREaXNjb25uZWN0ZWQoY3R4ID0+IHtcbiAgY29uc3QgdXNlciA9IGN0eC5kYi51c2VyLmlkZW50aXR5LmZpbmQoY3R4LnNlbmRlcik7XG4gIGlmICh1c2VyKSB7XG4gICAgY3R4LmRiLnVzZXIuaWRlbnRpdHkudXBkYXRlKHsgLi4udXNlciwgb25saW5lOiBmYWxzZSB9KTtcbiAgfVxuICAvLyBBdXRvLWxlYXZlIHZvaWNlIG9uIGRpc2Nvbm5lY3RcbiAgY3R4LmRiLnZvaWNlX3N0YXRlLmlkZW50aXR5LmRlbGV0ZShjdHguc2VuZGVyKTtcbiAgLy8gQ2xlYW4gdXAgc2lnbmFsaW5nIG1lc3NhZ2VzIGFzc29jaWF0ZWQgd2l0aCB0aGUgZGlzY29ubmVjdGVkIHVzZXJcbiAgY2xlYXJTaWduYWxpbmdGb3JVc2VyKGN0eCwgY3R4LnNlbmRlcik7XG59KTtcbiJdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLElBQUlBLGFBQVcsT0FBTztBQUN0QixJQUFJQyxjQUFZLE9BQU87QUFDdkIsSUFBSUMscUJBQW1CLE9BQU87QUFDOUIsSUFBSUMsc0JBQW9CLE9BQU87QUFDL0IsSUFBSUMsaUJBQWUsT0FBTztBQUMxQixJQUFJQyxpQkFBZSxPQUFPLFVBQVU7QUFDcEMsSUFBSUMsZ0JBQWMsSUFBSSxRQUFRLFNBQVMsWUFBWTtBQUNqRCxRQUFPLFFBQVEsR0FBRyxHQUFHSCxvQkFBa0IsR0FBRyxDQUFDLE1BQU0sTUFBTSxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsU0FBUyxJQUFJLEVBQUUsSUFBSTs7QUFFN0YsSUFBSUksaUJBQWUsSUFBSSxNQUFNLFFBQVEsU0FBUztBQUM1QyxLQUFJLFFBQVEsT0FBTyxTQUFTLFlBQVksT0FBTyxTQUFTLFlBQ3REO09BQUssSUFBSSxPQUFPSixvQkFBa0IsS0FBSyxDQUNyQyxLQUFJLENBQUNFLGVBQWEsS0FBSyxJQUFJLElBQUksSUFBSSxRQUFRLE9BQ3pDLGFBQVUsSUFBSSxLQUFLO0dBQUUsV0FBVyxLQUFLO0dBQU0sWUFBWSxFQUFFLE9BQU9ILG1CQUFpQixNQUFNLElBQUksS0FBSyxLQUFLO0dBQVksQ0FBQzs7QUFFeEgsUUFBTzs7QUFFVCxJQUFJTSxhQUFXLEtBQUssWUFBWSxZQUFZLFNBQVMsT0FBTyxPQUFPUixXQUFTSSxlQUFhLElBQUksQ0FBQyxHQUFHLEVBQUUsRUFBRUcsY0FLbkcsY0FBYyxDQUFDLE9BQU8sQ0FBQyxJQUFJLGFBQWFOLFlBQVUsUUFBUSxXQUFXO0NBQUUsT0FBTztDQUFLLFlBQVk7Q0FBTSxD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 \ No newline at end of file diff --git a/spacetimedb/node_modules/.bin/tsc b/spacetimedb/node_modules/.bin/tsc new file mode 100755 index 0000000..d8046ac --- /dev/null +++ b/spacetimedb/node_modules/.bin/tsc @@ -0,0 +1,21 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/Users/alamers/git/my-spacetime-app/spacetimedb/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/Users/alamers/git/my-spacetime-app/spacetimedb/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/Users/alamers/git/my-spacetime-app/spacetimedb/node_modules/.pnpm/typescript@5.9.3/node_modules:/Users/alamers/git/my-spacetime-app/spacetimedb/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/Users/alamers/git/my-spacetime-app/spacetimedb/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/Users/alamers/git/my-spacetime-app/spacetimedb/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/Users/alamers/git/my-spacetime-app/spacetimedb/node_modules/.pnpm/typescript@5.9.3/node_modules:/Users/alamers/git/my-spacetime-app/spacetimedb/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@" +else + exec node "$basedir/../typescript/bin/tsc" "$@" +fi diff --git a/spacetimedb/node_modules/.bin/tsserver b/spacetimedb/node_modules/.bin/tsserver new file mode 100755 index 0000000..061b8ce --- /dev/null +++ b/spacetimedb/node_modules/.bin/tsserver @@ -0,0 +1,21 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/Users/alamers/git/my-spacetime-app/spacetimedb/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/Users/alamers/git/my-spacetime-app/spacetimedb/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/Users/alamers/git/my-spacetime-app/spacetimedb/node_modules/.pnpm/typescript@5.9.3/node_modules:/Users/alamers/git/my-spacetime-app/spacetimedb/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/Users/alamers/git/my-spacetime-app/spacetimedb/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/Users/alamers/git/my-spacetime-app/spacetimedb/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/Users/alamers/git/my-spacetime-app/spacetimedb/node_modules/.pnpm/typescript@5.9.3/node_modules:/Users/alamers/git/my-spacetime-app/spacetimedb/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@" +else + exec node "$basedir/../typescript/bin/tsserver" "$@" +fi diff --git a/spacetimedb/node_modules/.modules.yaml b/spacetimedb/node_modules/.modules.yaml new file mode 100644 index 0000000..63dde22 --- /dev/null +++ b/spacetimedb/node_modules/.modules.yaml @@ -0,0 +1,51 @@ +{ + "hoistedDependencies": { + "headers-polyfill@4.0.3": { + "headers-polyfill": "private" + }, + "base64-js@1.5.1": { + "base64-js": "private" + }, + "url-polyfill@1.1.14": { + "url-polyfill": "private" + }, + "object-inspect@1.13.4": { + "object-inspect": "private" + }, + "pure-rand@7.0.1": { + "pure-rand": "private" + }, + "statuses@2.0.2": { + "statuses": "private" + }, + "safe-stable-stringify@2.5.0": { + "safe-stable-stringify": "private" + }, + "prettier@3.8.1": { + "prettier": "private" + } + }, + "hoistPattern": [ + "*" + ], + "included": { + "dependencies": true, + "devDependencies": true, + "optionalDependencies": true + }, + "injectedDeps": {}, + "layoutVersion": 5, + "nodeLinker": "isolated", + "packageManager": "pnpm@10.29.3", + "pendingBuilds": [], + "publicHoistPattern": [], + "prunedAt": "Sat, 28 Mar 2026 23:54:58 GMT", + "registries": { + "default": "https://registry.npmjs.org/", + "@jsr": "https://npm.jsr.io/" + }, + "skipped": [], + "storeDir": "/Users/alamers/Library/pnpm/store/v10", + "virtualStoreDir": ".pnpm", + "virtualStoreDirMaxLength": 120 +} \ No newline at end of file diff --git a/spacetimedb/node_modules/.pnpm-workspace-state-v1.json b/spacetimedb/node_modules/.pnpm-workspace-state-v1.json new file mode 100644 index 0000000..96e245d --- /dev/null +++ b/spacetimedb/node_modules/.pnpm-workspace-state-v1.json @@ -0,0 +1,25 @@ +{ + "lastValidatedTimestamp": 1774742098032, + "projects": {}, + "pnpmfiles": [], + "settings": { + "autoInstallPeers": true, + "dedupeDirectDeps": false, + "dedupeInjectedDeps": true, + "dedupePeerDependents": true, + "dev": true, + "excludeLinksFromLockfile": false, + "hoistPattern": [ + "*" + ], + "hoistWorkspacePackages": true, + "injectWorkspacePackages": false, + "linkWorkspacePackages": false, + "nodeLinker": "isolated", + "optional": true, + "preferWorkspacePackages": false, + "production": true, + "publicHoistPattern": [] + }, + "filteredInstall": false +} diff --git a/spacetimedb/node_modules/spacetimedb b/spacetimedb/node_modules/spacetimedb new file mode 120000 index 0000000..dc7e627 --- /dev/null +++ b/spacetimedb/node_modules/spacetimedb @@ -0,0 +1 @@ +.pnpm/spacetimedb@2.1.0/node_modules/spacetimedb \ No newline at end of file diff --git a/spacetimedb/node_modules/typescript b/spacetimedb/node_modules/typescript new file mode 120000 index 0000000..e5bbb7f --- /dev/null +++ b/spacetimedb/node_modules/typescript @@ -0,0 +1 @@ +.pnpm/typescript@5.9.3/node_modules/typescript \ No newline at end of file diff --git a/spacetimedb/package-lock.json b/spacetimedb/package-lock.json new file mode 100644 index 0000000..69a1f0a --- /dev/null +++ b/spacetimedb/package-lock.json @@ -0,0 +1,113 @@ +{ + "name": "sdk-test-module", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "sdk-test-module", + "license": "ISC", + "dependencies": { + "fast-text-encoding": "^1.0.0" + }, + "devDependencies": { + "@types/fast-text-encoding": "^1.0.3", + "tsup": "^8.1.0" + } + }, + "../../node_modules/.pnpm/fast-text-encoding@1.0.6/node_modules/fast-text-encoding": { + "version": "1.0.6", + "license": "Apache-2.0" + }, + "../../node_modules/.pnpm/tsup@8.5.0_jiti@2.5.1_postcss@8.5.6_tsx@4.20.4_typescript@5.9.2/node_modules/tsup": { + "version": "8.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-require": "^5.1.0", + "cac": "^6.7.14", + "chokidar": "^4.0.3", + "consola": "^3.4.0", + "debug": "^4.4.0", + "esbuild": "^0.25.0", + "fix-dts-default-cjs-exports": "^1.0.0", + "joycon": "^3.1.1", + "picocolors": "^1.1.1", + "postcss-load-config": "^6.0.1", + "resolve-from": "^5.0.0", + "rollup": "^4.34.8", + "source-map": "0.8.0-beta.0", + "sucrase": "^3.35.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.11", + "tree-kill": "^1.2.2" + }, + "bin": { + "tsup": "dist/cli-default.js", + "tsup-node": "dist/cli-node.js" + }, + "devDependencies": { + "@microsoft/api-extractor": "^7.50.0", + "@rollup/plugin-json": "6.1.0", + "@swc/core": "1.10.18", + "@types/debug": "4.1.12", + "@types/node": "22.13.4", + "@types/resolve": "1.20.6", + "bumpp": "^10.0.3", + "flat": "6.0.1", + "postcss": "8.5.2", + "postcss-simple-vars": "7.0.1", + "prettier": "3.5.1", + "resolve": "1.22.10", + "rollup-plugin-dts": "6.1.1", + "sass": "1.85.0", + "strip-json-comments": "5.0.1", + "svelte": "5.19.9", + "svelte-preprocess": "6.0.3", + "terser": "^5.39.0", + "ts-essentials": "10.0.4", + "tsup": "8.3.6", + "typescript": "5.7.3", + "vitest": "3.0.6", + "wait-for-expect": "3.0.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7.36.0", + "@swc/core": "^1", + "postcss": "^8.4.12", + "typescript": ">=4.5.0" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "postcss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/@types/fast-text-encoding": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz", + "integrity": "sha512-bbGJt6IyiuyAhPOX7htQDDzv2bDGJdWyd6X+e1BcdPzU3e5jyjOdB86LoTSoE80faY9v8Wt7/ix3Sp+coRJ03Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-text-encoding": { + "resolved": "../../node_modules/.pnpm/fast-text-encoding@1.0.6/node_modules/fast-text-encoding", + "link": true + }, + "node_modules/tsup": { + "resolved": "../../node_modules/.pnpm/tsup@8.5.0_jiti@2.5.1_postcss@8.5.6_tsx@4.20.4_typescript@5.9.2/node_modules/tsup", + "link": true + } + } +} diff --git a/spacetimedb/package.json b/spacetimedb/package.json new file mode 100644 index 0000000..3adcce6 --- /dev/null +++ b/spacetimedb/package.json @@ -0,0 +1,16 @@ +{ + "name": "my-spacetime-app", + "license": "ISC", + "type": "module", + "scripts": { + "build": "cargo build -p spacetimedb-standalone && cargo run -p spacetimedb-cli -- build", + "generate-ts": "cargo build -p spacetimedb-standalone && cargo run -p spacetimedb-cli -- generate --lang typescript --out-dir ts-codegen", + "publish": "cargo run -p spacetimedb-cli -- publish" + }, + "dependencies": { + "spacetimedb": "^2.1.0" + }, + "devDependencies": { + "typescript": "^5.9.3" + } +} \ No newline at end of file diff --git a/spacetimedb/pnpm-lock.yaml b/spacetimedb/pnpm-lock.yaml new file mode 100644 index 0000000..ce33884 --- /dev/null +++ b/spacetimedb/pnpm-lock.yaml @@ -0,0 +1,107 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + spacetimedb: + specifier: ^2.1.0 + version: 2.1.0 + devDependencies: + typescript: + specifier: ^5.9.3 + version: 5.9.3 + +packages: + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + headers-polyfill@4.0.3: + resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} + engines: {node: '>=14'} + hasBin: true + + pure-rand@7.0.1: + resolution: {integrity: sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + spacetimedb@2.1.0: + resolution: {integrity: sha512-Kzs+HXCRj15ryld03ztU4a2uQg0M8ivV/9Bk/gvMpb59lLc/A2/r7UkGCYBePsBL7Zwqgr8gE8FeufoZVXtPnA==} + peerDependencies: + '@angular/core': '>=17.0.0' + '@tanstack/react-query': ^5.0.0 + react: ^18.0.0 || ^19.0.0-0 || ^19.0.0 + svelte: ^4.0.0 || ^5.0.0 + undici: ^6.19.2 + vue: ^3.3.0 + peerDependenciesMeta: + '@angular/core': + optional: true + '@tanstack/react-query': + optional: true + react: + optional: true + svelte: + optional: true + undici: + optional: true + vue: + optional: true + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + url-polyfill@1.1.14: + resolution: {integrity: sha512-p4f3TTAG6ADVF3mwbXw7hGw+QJyw5CnNGvYh5fCuQQZIiuKUswqcznyV3pGDP9j0TSmC4UvRKm8kl1QsX1diiQ==} + +snapshots: + + base64-js@1.5.1: {} + + headers-polyfill@4.0.3: {} + + object-inspect@1.13.4: {} + + prettier@3.8.1: {} + + pure-rand@7.0.1: {} + + safe-stable-stringify@2.5.0: {} + + spacetimedb@2.1.0: + dependencies: + base64-js: 1.5.1 + headers-polyfill: 4.0.3 + object-inspect: 1.13.4 + prettier: 3.8.1 + pure-rand: 7.0.1 + safe-stable-stringify: 2.5.0 + statuses: 2.0.2 + url-polyfill: 1.1.14 + + statuses@2.0.2: {} + + typescript@5.9.3: {} + + url-polyfill@1.1.14: {} diff --git a/spacetimedb/src/index.ts b/spacetimedb/src/index.ts new file mode 100644 index 0000000..1428544 --- /dev/null +++ b/spacetimedb/src/index.ts @@ -0,0 +1,430 @@ +import { schema, t, table, SenderError } from 'spacetimedb/server'; + +const channel_kind = t.enum('ChannelKind', { text: t.unit(), voice: t.unit() }); + +const user = table( + { + name: 'user', + public: true, + }, + { + identity: t.identity().primaryKey(), + name: t.string().optional(), + online: t.bool(), + issuer: t.string().optional(), + subject: t.string().optional(), + username: t.string().optional(), // For creds-based auth + password: t.string().optional(), // For creds-based auth (Note: plain text for MVP) + } +); + +const server = table( + { name: 'server', public: true }, + { + id: t.u64().primaryKey().autoInc(), + name: t.string(), + owner: t.identity().optional(), + } +); + +const channel = table( + { + name: 'channel', + public: true, + indexes: [ + { accessor: 'by_server_id', algorithm: 'btree', columns: ['server_id'] } + ] + }, + { + id: t.u64().primaryKey().autoInc(), + server_id: t.u64(), + name: t.string(), + kind: channel_kind, + } +); + +const voice_state = table( + { + name: 'voice_state', + public: true, + indexes: [ + { accessor: 'by_channel_id', algorithm: 'btree', columns: ['channel_id'] } + ] + }, + { + identity: t.identity().primaryKey(), + channel_id: t.u64(), + } +); + +const sdp_offer = table( + { + name: 'sdp_offer', + public: true, + indexes: [ + { accessor: 'by_receiver', algorithm: 'btree', columns: ['receiver'] } + ] + }, + { + sender: t.identity(), + receiver: t.identity(), + sdp: t.string(), + channel_id: t.u64(), + } +); + +const sdp_answer = table( + { + name: 'sdp_answer', + public: true, + indexes: [ + { accessor: 'by_receiver', algorithm: 'btree', columns: ['receiver'] } + ] + }, + { + sender: t.identity(), + receiver: t.identity(), + sdp: t.string(), + channel_id: t.u64(), + } +); + +const ice_candidate = table( + { + name: 'ice_candidate', + public: true, + indexes: [ + { accessor: 'by_receiver', algorithm: 'btree', columns: ['receiver'] } + ] + }, + { + sender: t.identity(), + receiver: t.identity(), + candidate: t.string(), + channel_id: t.u64(), + } +); + +const thread = table( + { + name: 'thread', + public: true, + indexes: [ + { accessor: 'by_channel_id', algorithm: 'btree', columns: ['channel_id'] } + ] + }, + { + id: t.u64().primaryKey().autoInc(), + channel_id: t.u64(), + parent_message_id: t.u64().unique(), + name: t.string(), + } +); + +const message = table( + { + name: 'message', + public: true, + indexes: [ + { accessor: 'by_channel_id', algorithm: 'btree', columns: ['channel_id'] }, + { accessor: 'by_thread_id', algorithm: 'btree', columns: ['thread_id'] } + ] + }, + { + id: t.u64().primaryKey().autoInc(), + sender: t.identity(), + sent: t.timestamp(), + text: t.string(), + channel_id: t.u64(), + thread_id: t.u64().optional(), + } +); + +const spacetimedb = schema({ user, server, channel, voice_state, sdp_offer, sdp_answer, ice_candidate, thread, message }); +export default spacetimedb; + +function validateName(name: string) { + if (!name || name.trim().length === 0) throw new SenderError('Names must not be empty'); +} + +export const set_name = spacetimedb.reducer( + { name: t.string() }, + (ctx, { name }) => { + validateName(name); + const user = ctx.db.user.identity.find(ctx.sender); + if (!user) throw new SenderError('Cannot set name for unknown user'); + ctx.db.user.identity.update({ ...user, name }); + } +); + +export const register = spacetimedb.reducer( + { username: t.string(), password: t.string() }, + (ctx, { username, password }) => { + validateName(username); + if (!password || password.length < 4) throw new SenderError('Password must be at least 4 characters'); + + for (const u of ctx.db.user.iter()) { + if (u.username === username) { + throw new SenderError('Username already taken'); + } + } + + const user = ctx.db.user.identity.find(ctx.sender); + if (user) { + ctx.db.user.identity.update({ + ...user, + username, + password, + name: user.name || username + }); + } else { + ctx.db.user.insert({ + identity: ctx.sender, + username, + password, + name: username, + online: true, + issuer: undefined, + subject: undefined + }); + } + } +); + +export const login = spacetimedb.reducer( + { username: t.string(), password: t.string() }, + (ctx, { username, password }) => { + let foundUser = null; + for (const u of ctx.db.user.iter()) { + if (u.username === username && u.password === password) { + foundUser = u; + break; + } + } + + if (!foundUser) { + throw new SenderError('Invalid username or password'); + } + + const currentIdentityUser = ctx.db.user.identity.find(ctx.sender); + if (currentIdentityUser && currentIdentityUser.identity.toHexString() !== foundUser.identity.toHexString()) { + ctx.db.user.identity.delete(ctx.sender); + } + + if (foundUser.identity.toHexString() !== ctx.sender.toHexString()) { + ctx.db.user.identity.delete(foundUser.identity); + ctx.db.user.insert({ + ...foundUser, + identity: ctx.sender, + online: true + }); + } else { + ctx.db.user.identity.update({ + ...foundUser, + online: true + }); + } + } +); + +export const create_server = spacetimedb.reducer( + { name: t.string() }, + (ctx, { name }) => { + validateName(name); + const user = ctx.db.user.identity.find(ctx.sender); + if (!user || (!user.username && !user.subject)) { + throw new SenderError('You must be logged in to create a server'); + } + const s = ctx.db.server.insert({ id: 0n, name, owner: ctx.sender }); + ctx.db.channel.insert({ id: 0n, server_id: s.id, name: 'general', kind: { tag: 'text' } }); + ctx.db.channel.insert({ id: 0n, server_id: s.id, name: 'Voice General', kind: { tag: 'voice' } }); + } +); + +export const create_channel = spacetimedb.reducer( + { name: t.string(), serverId: t.u64(), isVoice: t.bool() }, + (ctx, { name, serverId, isVoice }) => { + validateName(name); + const user = ctx.db.user.identity.find(ctx.sender); + if (!user || (!user.username && !user.subject)) { + throw new SenderError('You must be logged in to create a channel'); + } + const s = ctx.db.server.id.find(serverId); + if (!s) throw new SenderError('Server not found'); + ctx.db.channel.insert({ + id: 0n, + server_id: serverId, + name, + kind: isVoice ? { tag: 'voice' } : { tag: 'text' } + }); + } +); + +export const join_voice = spacetimedb.reducer( + { channelId: t.u64() }, + (ctx, { channelId }) => { + const user = ctx.db.user.identity.find(ctx.sender); + if (!user || (!user.username && !user.subject)) { + throw new SenderError('You must be logged in to join voice'); + } + const chan = ctx.db.channel.id.find(channelId); + if (!chan || chan.kind.tag !== 'voice') throw new SenderError('Invalid voice channel'); + + const existing = ctx.db.voice_state.identity.find(ctx.sender); + if (existing) { + if (existing.channel_id !== channelId) { + clearSignalingForUser(ctx, ctx.sender); + ctx.db.voice_state.identity.update({ identity: ctx.sender, channel_id: channelId }); + } + } else { + ctx.db.voice_state.insert({ identity: ctx.sender, channel_id: channelId }); + } + } +); + +export const leave_voice = spacetimedb.reducer((ctx) => { + ctx.db.voice_state.identity.delete(ctx.sender); + clearSignalingForUser(ctx, ctx.sender); +}); + +export const send_sdp_offer = spacetimedb.reducer( + { receiver: t.identity(), sdp: t.string(), channelId: t.u64() }, + (ctx, { receiver, sdp, channelId }) => { + ctx.db.sdp_offer.insert({ sender: ctx.sender, receiver, sdp, channel_id: channelId }); + } +); + +export const send_sdp_answer = spacetimedb.reducer( + { receiver: t.identity(), sdp: t.string(), channelId: t.u64() }, + (ctx, { receiver, sdp, channelId }) => { + ctx.db.sdp_answer.insert({ sender: ctx.sender, receiver, sdp, channel_id: channelId }); + } +); + +export const send_ice_candidate = spacetimedb.reducer( + { receiver: t.identity(), candidate: t.string(), channelId: t.u64() }, + (ctx, { receiver, candidate, channelId }) => { + ctx.db.ice_candidate.insert({ sender: ctx.sender, receiver, candidate, channel_id: channelId }); + } +); + +function clearSignalingForUser(ctx: any, identity: any) { + // Clean up stale signaling messages for the user + // Note: Iterating and deleting might not be the most performant for large tables. + // In a production scenario, consider TTLs or more targeted deletion strategies. + + const userOffers = ctx.db.sdp_offer.iter().filter((offer: any) => + offer.sender.isEqual(identity) || offer.receiver.isEqual(identity) + ); + for (const offer of userOffers) { + ctx.db.sdp_offer.delete(offer.id); // Assuming 'id' is the primary key + } + + const userAnswers = ctx.db.sdp_answer.iter().filter((answer: any) => + answer.sender.isEqual(identity) || answer.receiver.isEqual(identity) + ); + for (const answer of userAnswers) { + ctx.db.sdp_answer.delete(answer.id); // Assuming 'id' is the primary key + } + + const userCandidates = ctx.db.ice_candidate.iter().filter((candidate: any) => + candidate.sender.isEqual(identity) || candidate.receiver.isEqual(identity) + ); + for (const candidate of userCandidates) { + ctx.db.ice_candidate.delete(candidate.id); // Assuming 'id' is the primary key + } +} + +export const create_thread = spacetimedb.reducer( + { name: t.string(), channelId: t.u64(), parentMessageId: t.u64() }, + (ctx, { name, channelId, parentMessageId }) => { + validateName(name); + const user = ctx.db.user.identity.find(ctx.sender); + if (!user || (!user.username && !user.subject)) { + throw new SenderError('You must be logged in to create a thread'); + } + const parentMsg = ctx.db.message.id.find(parentMessageId); + if (!parentMsg) throw new SenderError('Parent message not found'); + + ctx.db.thread.insert({ id: 0n, channel_id: channelId, parent_message_id: parentMessageId, name }); + } +); + +export const send_message = spacetimedb.reducer( + { text: t.string(), channelId: t.u64(), threadId: t.u64().optional() }, + (ctx, { text, channelId, threadId }) => { + if (!text || text.trim().length === 0) throw new SenderError('Messages must not be empty'); + + const user = ctx.db.user.identity.find(ctx.sender); + if (!user || (!user.username && !user.subject)) { + throw new SenderError('You must be logged in to send messages'); + } + + ctx.db.message.insert({ + id: 0n, + sender: ctx.sender, + text, + sent: ctx.timestamp, + channel_id: channelId, + thread_id: threadId, + }); + } +); + +export const init = spacetimedb.init(ctx => { + let hasServers = false; + for (const _ of ctx.db.server.iter()) { + hasServers = true; + break; + } + if (!hasServers) { + const s = ctx.db.server.insert({ id: 0n, name: 'Spacetime Community', owner: undefined }); + ctx.db.channel.insert({ id: 0n, server_id: s.id, name: 'general', kind: { tag: 'text' } }); + ctx.db.channel.insert({ id: 0n, server_id: s.id, name: 'Voice General', kind: { tag: 'voice' } }); + } +}); + +export const onConnect = spacetimedb.clientConnected(ctx => { + const user = ctx.db.user.identity.find(ctx.sender); + + if (ctx.senderAuth.hasJWT && ctx.senderAuth.jwt) { + const jwt = ctx.senderAuth.jwt; + const issuer = jwt.issuer; + const subject = jwt.subject; + const payload = jwt.fullPayload; + const name = (payload.name as string) || (payload.nickname as string) || (payload.preferred_username as string) || (payload.email as string); + + if (user) { + ctx.db.user.identity.update({ + ...user, + online: true, + name: user.name || name, + issuer, + subject + }); + } else { + ctx.db.user.insert({ + name, + identity: ctx.sender, + online: true, + issuer, + subject, + username: undefined, + password: undefined + }); + } + } else if (user) { + ctx.db.user.identity.update({ ...user, online: true }); + } +}); + +export const onDisconnect = spacetimedb.clientDisconnected(ctx => { + const user = ctx.db.user.identity.find(ctx.sender); + if (user) { + ctx.db.user.identity.update({ ...user, online: false }); + } + // Auto-leave voice on disconnect + ctx.db.voice_state.identity.delete(ctx.sender); + // Clean up signaling messages associated with the disconnected user + clearSignalingForUser(ctx, ctx.sender); +}); diff --git a/spacetimedb/tsconfig.json b/spacetimedb/tsconfig.json new file mode 100644 index 0000000..9446cbd --- /dev/null +++ b/spacetimedb/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + + "strict": true, + "declaration": false, + "emitDeclarationOnly": false, + "noEmit": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "allowImportingTsExtensions": true, + "noImplicitAny": true, + "moduleResolution": "bundler", + "isolatedDeclarations": false, + + // This library is ESM-only, do not import commonjs modules + "esModuleInterop": false, + "allowSyntheticDefaultImports": false, + "useDefineForClassFields": true, + + // Crucial when using esbuild/swc/babel instead of tsc emit: + "verbatimModuleSyntax": true, + "isolatedModules": true + }, + "include": ["src/index.ts", "tests/**/*"], + "exclude": ["node_modules", "**/__tests__/*", "dist/**/*"] +} diff --git a/src/.gitattributes b/src/.gitattributes new file mode 100644 index 0000000..f4d6534 --- /dev/null +++ b/src/.gitattributes @@ -0,0 +1 @@ +/module_bindings/** linguist-generated=true diff --git a/src/App.css b/src/App.css new file mode 100644 index 0000000..57990a7 --- /dev/null +++ b/src/App.css @@ -0,0 +1,455 @@ +:root { + --background-primary: #313338; + --background-secondary: #2b2d31; + --background-tertiary: #1e1f22; + --background-accent: #404249; + --channel-sidebar-width: 240px; + --server-sidebar-width: 72px; + --text-normal: #dbdee1; + --text-muted: #949ba4; + --header-primary: #ffffff; + --interactive-normal: #b5bac1; + --interactive-hover: #dbdee1; + --interactive-active: #ffffff; + --brand: #5865f2; + --brand-hover: #4752c4; +} + +body { + margin: 0; + padding: 0; + background-color: var(--background-tertiary); + color: var(--text-normal); + font-family: 'gg sans', 'Noto Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; + overflow: hidden; +} + +.app-container { + display: flex; + height: 100vh; + width: 100vw; +} + +/* Login Screen */ +.login-screen { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100vh; + width: 100vw; + background-color: var(--background-tertiary); + gap: 20px; +} + +.login-card { + background-color: var(--background-primary); + padding: 32px; + border-radius: 8px; + box-shadow: 0 2px 10px 0 rgba(0,0,0,0.2); + display: flex; + flex-direction: column; + align-items: center; + gap: 24px; + width: 400px; +} + +.login-card h1 { + margin: 0; + color: var(--header-primary); +} + +.login-card p { + color: var(--text-muted); + text-align: center; + margin: 0; +} + +/* Sidebar for Servers (simplified icons) */ +.server-sidebar { + width: var(--server-sidebar-width); + background-color: var(--background-tertiary); + display: flex; + flex-direction: column; + align-items: center; + padding-top: 12px; + gap: 8px; +} + +.server-icon { + width: 48px; + height: 48px; + background-color: var(--background-accent); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: border-radius 0.2s, background-color 0.2s; + color: var(--text-normal); +} + +.server-icon:hover { + border-radius: 16px; + background-color: var(--brand); +} + +.server-icon.active { + border-radius: 16px; + background-color: var(--brand); +} + +/* Sidebar for Channels */ +.channel-sidebar { + width: var(--channel-sidebar-width); + background-color: var(--background-secondary); + display: flex; + flex-direction: column; +} + +.channel-header { + height: 48px; + padding: 0 16px; + display: flex; + align-items: center; + box-shadow: 0 1px 0 rgba(0,0,0,0.2); + font-weight: bold; + color: var(--header-primary); +} + +.channel-list { + flex: 1; + padding: 8px; + overflow-y: auto; +} + +.channel-item { + padding: 6px 8px; + border-radius: 4px; + cursor: pointer; + display: flex; + align-items: center; + color: var(--interactive-normal); + margin-bottom: 2px; +} + +.channel-item:hover { + background-color: var(--background-accent); + color: var(--interactive-hover); +} + +.channel-item.active { + background-color: var(--background-accent); + color: var(--interactive-active); +} + +.channel-item-hash { + margin-right: 6px; + color: var(--text-muted); + font-size: 1.2rem; +} + +/* User Profile at bottom of sidebar */ +.user-profile { + height: 52px; + background-color: #232428; + display: flex; + align-items: center; + padding: 0 8px; + gap: 8px; +} + +.avatar { + width: 32px; + height: 32px; + background-color: #5865f2; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + font-size: 0.8rem; + color: white; +} + +.user-info { + flex: 1; + overflow: hidden; +} + +.username { + font-size: 0.85rem; + font-weight: 600; + color: var(--header-primary); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.user-status { + font-size: 0.75rem; + color: var(--text-muted); +} + +/* Main Chat Area */ +.main-content { + flex: 1; + display: flex; + flex-direction: column; + background-color: var(--background-primary); +} + +.chat-header { + height: 48px; + padding: 0 16px; + display: flex; + align-items: center; + box-shadow: 0 1px 0 rgba(0,0,0,0.2); + color: var(--header-primary); + font-weight: bold; +} + +.messages-container { + flex: 1; + overflow-y: auto; + padding: 16px; + display: flex; + flex-direction: column; + gap: 16px; +} + +.message { + display: flex; + gap: 16px; +} + +.message-avatar { + width: 40px; + height: 40px; + background-color: #5865f2; + border-radius: 50%; + margin-top: 2px; + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; + color: white; +} + +.message-content { + flex: 1; +} + +.message-meta { + display: flex; + align-items: baseline; + gap: 8px; + margin-bottom: 4px; +} + +.message-sender { + font-weight: 500; + color: var(--header-primary); +} + +.message-timestamp { + font-size: 0.75rem; + color: var(--text-muted); +} + +.message-text { + color: var(--text-normal); + line-height: 1.375rem; + word-wrap: break-word; +} + +.message-thread-btn { + font-size: 0.75rem; + color: var(--brand); + background: none; + border: none; + cursor: pointer; + padding: 0; + margin-top: 4px; +} + +.message-thread-btn:hover { + text-decoration: underline; +} + +/* Chat Input */ +.chat-input-container { + padding: 0 16px 24px 16px; +} + +.chat-input-wrapper { + background-color: #383a40; + border-radius: 8px; + padding: 11px 16px; + display: flex; + align-items: center; +} + +.chat-input { + flex: 1; + background: none; + border: none; + color: var(--text-normal); + font-family: inherit; + font-size: 1rem; + outline: none; +} + +.chat-input::placeholder { + color: var(--text-muted); +} + +/* Right Sidebar (Users/Thread) */ +.right-sidebar { + width: 240px; + background-color: var(--background-secondary); + display: flex; + flex-direction: column; + border-left: 1px solid rgba(255,255,255,0.05); +} + +.thread-view { + display: flex; + flex-direction: column; + height: 100%; +} + +.thread-header { + height: 48px; + padding: 0 16px; + display: flex; + align-items: center; + justify-content: space-between; + box-shadow: 0 1px 0 rgba(0,0,0,0.2); + font-weight: bold; +} + +.close-btn { + background: none; + border: none; + color: var(--interactive-normal); + cursor: pointer; + font-size: 1.2rem; +} + +.thread-messages { + flex: 1; + overflow-y: auto; + padding: 8px; +} + +.member-list { + padding: 16px 8px; +} + +.member-item { + display: flex; + align-items: center; + gap: 8px; + padding: 6px 8px; + border-radius: 4px; + color: var(--text-muted); +} + +.member-item:hover { + background-color: var(--background-accent); + color: var(--interactive-hover); +} + +.member-avatar { + width: 32px; + height: 32px; + background-color: #5865f2; + border-radius: 50%; +} + +.member-name { + font-size: 0.9rem; + font-weight: 500; +} + +/* Modals/Dialogs */ +.modal-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0,0,0,0.85); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; +} + +.modal-content { + background-color: var(--background-primary); + padding: 24px; + border-radius: 8px; + width: 400px; + display: flex; + flex-direction: column; + gap: 16px; +} + +.modal-content h2 { + margin: 0; + color: var(--header-primary); +} + +.modal-content input { + background-color: var(--background-tertiary); + border: none; + padding: 12px; + border-radius: 4px; + color: var(--text-normal); + outline: none; +} + +.modal-buttons { + display: flex; + justify-content: flex-end; + gap: 8px; +} + +.btn-primary { + background-color: var(--brand); + color: white; + border: none; + padding: 10px 20px; + border-radius: 4px; + cursor: pointer; +} + +.btn-secondary { + background-color: transparent; + color: white; + border: none; + padding: 10px 20px; + cursor: pointer; +} + +.btn-danger { + background-color: #da373c; + color: white; + border: none; + padding: 10px 20px; + border-radius: 4px; + cursor: pointer; +} + +.btn-danger:hover { + background-color: #a12829; +} + +.add-btn { + background: none; + border: none; + color: var(--interactive-normal); + cursor: pointer; + font-size: 1.2rem; +} diff --git a/src/App.integration.test.tsx b/src/App.integration.test.tsx new file mode 100644 index 0000000..6e2bcd7 --- /dev/null +++ b/src/App.integration.test.tsx @@ -0,0 +1,76 @@ +import { render, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { describe, it, expect } from 'vitest'; +import App from './App'; +import { SpacetimeDBProvider } from 'spacetimedb/react'; +import { DbConnection } from './module_bindings'; + +describe('App Integration Test', () => { + it('connects to the DB, allows name change and message sending', async () => { + const connectionBuilder = DbConnection.builder() + .withUri('ws://localhost:3000') + .withDatabaseName('quickstart-chat') + .withToken( + localStorage.getItem( + 'ws://localhost:3000/quickstart-chat/auth_token' + ) || '' + ); + render( + + + + ); + + // Initially, we should see "Connecting..." + expect(screen.getByText(/Connecting.../i)).toBeInTheDocument(); + + // Wait until "Connecting..." is gone (meaning we've connected) + // This might require the actual DB to accept the connection + await waitFor( + () => + expect(screen.queryByText(/Connecting.../i)).not.toBeInTheDocument(), + { timeout: 10000 } + ); + + // The profile section should show the default name or truncated identity + // For example, you can check if the text is rendered. + // If your default identity is something like 'abcdef12' or 'Unknown' + // we do a generic check: + expect( + screen.getByRole('heading', { name: /profile/i }) + ).toBeInTheDocument(); + + // Let's change the user's name + const editNameButton = screen.getByText(/Edit Name/i); + await userEvent.click(editNameButton); + + const nameInput = screen.getByRole('textbox', { name: /name input/i }); + await userEvent.clear(nameInput); + await userEvent.type(nameInput, 'TestUser'); + const submitNameButton = screen.getByRole('button', { name: /submit/i }); + await userEvent.click(submitNameButton); + + // If your DB or UI updates instantly, we can check that the new name shows up + await waitFor( + () => { + expect(screen.getByText('TestUser')).toBeInTheDocument(); + }, + { timeout: 10000 } + ); + + // Now let's send a message + const textarea = screen.getByRole('textbox', { name: /message input/i }); + await userEvent.type(textarea, 'Hello from GH Actions!'); + + const sendButton = screen.getByRole('button', { name: /send/i }); + await userEvent.click(sendButton); + + // Wait for message to appear in the UI + await waitFor( + () => { + expect(screen.getByText('Hello from GH Actions!')).toBeInTheDocument(); + }, + { timeout: 10000 } + ); + }); +}); diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..3dfc635 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,653 @@ +import React, { useState, useMemo, useEffect, useCallback, useRef } from 'react'; +import './App.css'; +import { tables, reducers } from './module_bindings'; +import type * as Types from './module_bindings/types'; +import { useSpacetimeDB, useTable, useReducer } from 'spacetimedb/react'; +import { Identity } from 'spacetimedb'; +import { useAuth } from "react-oidc-context"; +import { TOKEN_KEY } from './main'; + +const VoiceAudio = ({ stream }: { stream?: MediaStream }) => { + const audioRef = React.useRef(null); + useEffect(() => { + if (audioRef.current && stream) { + audioRef.current.srcObject = stream; + } + }, [stream]); + return