commit b33fce53ddc381dba5266d9fc4895a5eed662b52 Author: Adam Lamers Date: Sat Mar 28 22:05:24 2026 -0400 initial commit 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