@simular-ai/sai-mcp 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -1
- package/dist/server.js +120 -23
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,8 @@ Simular's computer-use agent, #1 on OSWorld 2.0 (73%). Sai uses apps and
|
|
|
6
6
|
websites the way a person does, by seeing the screen, clicking and typing, so
|
|
7
7
|
your agent can get work done where there is no API: web apps behind a login,
|
|
8
8
|
admin consoles, desktop software, forms with no import. Sai runs on a
|
|
9
|
-
cloud computer we host
|
|
9
|
+
cloud computer we host (the free plan includes one) or on your own Mac or
|
|
10
|
+
Windows PC with the Sai Agent.
|
|
10
11
|
|
|
11
12
|
Run a workflow once and Sai can save it as code: later runs replay that code
|
|
12
13
|
and ask the model only where the screen matters, so they are faster and
|
|
@@ -43,6 +44,17 @@ already local, or you need exact, byte-for-byte output.
|
|
|
43
44
|
3. Next time: `Run invoice_export for vendor Acme, month March.` Sai replays
|
|
44
45
|
the code; when a step breaks because the UI changed, the agent takes over.
|
|
45
46
|
|
|
47
|
+
To get the code itself, to keep in your repo and run without the agent, ask
|
|
48
|
+
your coding agent:
|
|
49
|
+
|
|
50
|
+
```text
|
|
51
|
+
Use Sai to open TechCrunch, find all AI news published today, write their headlines into Notepad and save the file as techcrunch_headlines.txt, then turn what it did into code I can rerun.
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
It runs the task with `record_trajectory: true` and calls `sai_learn`, which
|
|
55
|
+
returns `async function main(params = { ... })` with the inputs it found as
|
|
56
|
+
parameters. See [Learned code](https://platform.simular.ai/documentation/concepts/learned-code).
|
|
57
|
+
|
|
46
58
|
The research behind it: [Neuro-Symbolic Computer Use](https://arxiv.org/abs/2609.36927)
|
|
47
59
|
(Sep 2026). Learned policies cut per-run cost 15–217× and latency 3.4–5.1×, and
|
|
48
60
|
raised Pass^3 by 3.6–15.8 points over the base agent on OSWorld-Verified and
|
|
@@ -128,6 +140,7 @@ Ask your agent something like:
|
|
|
128
140
|
| `sai_task_abort` | Stops a task. |
|
|
129
141
|
| `sai_upload` | Uploads a local file so a task can use it. |
|
|
130
142
|
| `sai_live_link` | A link to the computer's screen that you can use yourself, no sign-in. |
|
|
143
|
+
| `sai_learn` | Turns a finished task into code you can rerun without the agent. |
|
|
131
144
|
|
|
132
145
|
A task keeps running on the computer between calls. When Sai asks for
|
|
133
146
|
something only you can do, such as signing in to an account, your agent gives
|
package/dist/server.js
CHANGED
|
@@ -18946,11 +18946,11 @@ var Protocol = class {
|
|
|
18946
18946
|
const controller = this._requestHandlerAbortControllers.get(notification.params.requestId);
|
|
18947
18947
|
controller?.abort(notification.params.reason);
|
|
18948
18948
|
}
|
|
18949
|
-
_setupTimeout(messageId,
|
|
18949
|
+
_setupTimeout(messageId, timeout2, maxTotalTimeout, onTimeout, resetTimeoutOnProgress = false) {
|
|
18950
18950
|
this._timeoutInfo.set(messageId, {
|
|
18951
|
-
timeoutId: setTimeout(onTimeout,
|
|
18951
|
+
timeoutId: setTimeout(onTimeout, timeout2),
|
|
18952
18952
|
startTime: Date.now(),
|
|
18953
|
-
timeout,
|
|
18953
|
+
timeout: timeout2,
|
|
18954
18954
|
maxTotalTimeout,
|
|
18955
18955
|
resetTimeoutOnProgress,
|
|
18956
18956
|
onTimeout
|
|
@@ -19412,9 +19412,9 @@ var Protocol = class {
|
|
|
19412
19412
|
options?.signal?.addEventListener("abort", () => {
|
|
19413
19413
|
cancel(options?.signal?.reason);
|
|
19414
19414
|
});
|
|
19415
|
-
const
|
|
19416
|
-
const timeoutHandler = () => cancel(McpError.fromError(ErrorCode.RequestTimeout, "Request timed out", { timeout }));
|
|
19417
|
-
this._setupTimeout(messageId,
|
|
19415
|
+
const timeout2 = options?.timeout ?? DEFAULT_REQUEST_TIMEOUT_MSEC;
|
|
19416
|
+
const timeoutHandler = () => cancel(McpError.fromError(ErrorCode.RequestTimeout, "Request timed out", { timeout: timeout2 }));
|
|
19417
|
+
this._setupTimeout(messageId, timeout2, options?.maxTotalTimeout, timeoutHandler, options?.resetTimeoutOnProgress ?? false);
|
|
19418
19418
|
const relatedTaskId = relatedTask?.taskId;
|
|
19419
19419
|
if (relatedTaskId) {
|
|
19420
19420
|
const responseResolver = (response) => {
|
|
@@ -21436,7 +21436,7 @@ var StdioServerTransport = class {
|
|
|
21436
21436
|
};
|
|
21437
21437
|
|
|
21438
21438
|
// src/version.ts
|
|
21439
|
-
var SERVER_VERSION = "0.
|
|
21439
|
+
var SERVER_VERSION = "0.6.0";
|
|
21440
21440
|
|
|
21441
21441
|
// src/api.ts
|
|
21442
21442
|
var ApiError = class extends Error {
|
|
@@ -21661,7 +21661,8 @@ var SaiApi = class {
|
|
|
21661
21661
|
message: req.message,
|
|
21662
21662
|
...req.attachments && { attachments: req.attachments },
|
|
21663
21663
|
...req.model && { model: req.model },
|
|
21664
|
-
...req.autonomous && { autonomous: true }
|
|
21664
|
+
...req.autonomous && { autonomous: true },
|
|
21665
|
+
...req.recordTrajectory && { options: { recordTrajectory: true } }
|
|
21665
21666
|
}),
|
|
21666
21667
|
...signal && { signal },
|
|
21667
21668
|
prefix: "Failed to send the task"
|
|
@@ -21680,12 +21681,26 @@ var SaiApi = class {
|
|
|
21680
21681
|
wait: false,
|
|
21681
21682
|
...req.attachments && { attachments: req.attachments },
|
|
21682
21683
|
...req.model && { model: req.model },
|
|
21683
|
-
...req.autonomous && { autonomous: true }
|
|
21684
|
+
...req.autonomous && { autonomous: true },
|
|
21685
|
+
...req.recordTrajectory && { options: { recordTrajectory: true } }
|
|
21684
21686
|
}),
|
|
21685
21687
|
signal: AbortSignal.timeout(3e4),
|
|
21686
21688
|
prefix: "Failed to send the task"
|
|
21687
21689
|
});
|
|
21688
21690
|
}
|
|
21691
|
+
/**
|
|
21692
|
+
* `POST /v1/agents/learn` without `maxIterations`: writes the code from recorded turns and
|
|
21693
|
+
* answers when it is written, which can take minutes.
|
|
21694
|
+
*/
|
|
21695
|
+
learn(body) {
|
|
21696
|
+
return this.json("/v1/agents/learn", {
|
|
21697
|
+
method: "POST",
|
|
21698
|
+
headers: this.headers({ "Content-Type": "application/json" }),
|
|
21699
|
+
body: JSON.stringify(body),
|
|
21700
|
+
signal: AbortSignal.timeout(10 * 6e4),
|
|
21701
|
+
prefix: "Learning code failed"
|
|
21702
|
+
});
|
|
21703
|
+
}
|
|
21689
21704
|
/** A2: `GET /events?sessionId&since&wait` — long-polls up to `waitS` (0..60) seconds. */
|
|
21690
21705
|
events(sessionId, since, waitS) {
|
|
21691
21706
|
const params = new URLSearchParams({ sessionId, wait: String(waitS) });
|
|
@@ -21955,6 +21970,10 @@ var StreamCollector = class {
|
|
|
21955
21970
|
continue;
|
|
21956
21971
|
}
|
|
21957
21972
|
if (event.type === "start" || event.type === "data-session") continue;
|
|
21973
|
+
if (event.type === "data-turn") {
|
|
21974
|
+
tracked.turnId = event.data.turnId;
|
|
21975
|
+
continue;
|
|
21976
|
+
}
|
|
21958
21977
|
this.push(tracked, event);
|
|
21959
21978
|
}
|
|
21960
21979
|
if (!tracked) {
|
|
@@ -22018,6 +22037,9 @@ var StreamCollector = class {
|
|
|
22018
22037
|
tracked.notifier.signal();
|
|
22019
22038
|
}
|
|
22020
22039
|
}
|
|
22040
|
+
turnId(sessionId) {
|
|
22041
|
+
return this.sessions.get(sessionId)?.turnId;
|
|
22042
|
+
}
|
|
22021
22043
|
};
|
|
22022
22044
|
var EVENTS_MAX_WAIT_S = 60;
|
|
22023
22045
|
var APPROVAL_REPOLL_MS = 5e3;
|
|
@@ -22042,7 +22064,11 @@ var EventsPoller = class {
|
|
|
22042
22064
|
`Sai answered without starting a task: ${typeof reply === "string" ? reply : ""}`.trim()
|
|
22043
22065
|
);
|
|
22044
22066
|
}
|
|
22045
|
-
this.sessions.set(result.sessionId, {
|
|
22067
|
+
this.sessions.set(result.sessionId, {
|
|
22068
|
+
machineId: result.machineId,
|
|
22069
|
+
state: initialState(),
|
|
22070
|
+
...result.turnId && { turnId: result.turnId }
|
|
22071
|
+
});
|
|
22046
22072
|
return result;
|
|
22047
22073
|
}
|
|
22048
22074
|
/**
|
|
@@ -22126,6 +22152,9 @@ var EventsPoller = class {
|
|
|
22126
22152
|
noteApprovalResolved(approvalId) {
|
|
22127
22153
|
for (const polled of this.sessions.values()) markApprovalResolved(polled.state, approvalId);
|
|
22128
22154
|
}
|
|
22155
|
+
turnId(sessionId) {
|
|
22156
|
+
return this.sessions.get(sessionId)?.turnId;
|
|
22157
|
+
}
|
|
22129
22158
|
};
|
|
22130
22159
|
|
|
22131
22160
|
// src/tools.ts
|
|
@@ -22150,6 +22179,9 @@ var toolSchemas = {
|
|
|
22150
22179
|
),
|
|
22151
22180
|
autonomous: external_exports.boolean().optional().describe(
|
|
22152
22181
|
'true = run this task without approval prompts, as if "approve_for_task" had been answered up front; the grant ends with the task. Only when the user asked for the task to run unattended. Has no effect when the message steers a running task.'
|
|
22182
|
+
),
|
|
22183
|
+
record_trajectory: external_exports.boolean().optional().describe(
|
|
22184
|
+
"true = record the steps of this task so sai_learn can turn it into code afterwards. Set it when the user wants code, a script or a function from this task."
|
|
22153
22185
|
)
|
|
22154
22186
|
},
|
|
22155
22187
|
sai_models: {},
|
|
@@ -22173,6 +22205,13 @@ var toolSchemas = {
|
|
|
22173
22205
|
sai_upload: {
|
|
22174
22206
|
path: external_exports.string().min(1).describe("Absolute or cwd-relative path of a local file (max 25 MB).")
|
|
22175
22207
|
},
|
|
22208
|
+
sai_learn: {
|
|
22209
|
+
session_id: external_exports.string().min(1).describe("session_id from sai_task_start; its last task is turned into code."),
|
|
22210
|
+
task_template: external_exports.string().min(1).optional().describe(
|
|
22211
|
+
'The task with {{name}} placeholders for the inputs that should become parameters, e.g. "Open {{newsSite}}, find all {{topic}} news published today and save their headlines as {{fileName}}". Omit to let Sai find them.'
|
|
22212
|
+
),
|
|
22213
|
+
guidance: external_exports.string().min(1).optional().describe("The user's own knowledge for writing the code, e.g. which button is reliable.")
|
|
22214
|
+
},
|
|
22176
22215
|
sai_live_link: {
|
|
22177
22216
|
machine_id: external_exports.string().min(1).optional().describe(
|
|
22178
22217
|
"machine_id from sai_task_start or sai_machines. Optional when the account has exactly one machine."
|
|
@@ -22181,19 +22220,21 @@ var toolSchemas = {
|
|
|
22181
22220
|
};
|
|
22182
22221
|
var NO_SCREENSHOT = "Task tools return no screenshots: Sai sees the screen itself and reports back in text.";
|
|
22183
22222
|
var toolDescriptions = {
|
|
22184
|
-
sai_machines: "List the Sai machines (cloud computers or the user's own desktops) this account can drive. Returns { machines: [{ machineId, name, kind?, online? }], default? } \u2014 `default` is set when there is exactly one machine, in which case sai_task_start may omit machine_id. Call this once per conversation, not before every task. An empty list means the account has no computer yet: this server cannot create one (it costs money and needs the signed-in user), so send the user to https://platform.simular.ai/playground to create it in one click.",
|
|
22223
|
+
sai_machines: "List the Sai machines (cloud computers or the user's own desktops) this account can drive. Returns { machines: [{ machineId, name, kind?, online?, os? }], default? } \u2014 `default` is set when there is exactly one machine, in which case sai_task_start may omit machine_id. Call this once per conversation, not before every task. An empty list means the account has no computer yet: this server cannot create one (it costs money and needs the signed-in user), so send the user to https://platform.simular.ai/playground to create it in one click.",
|
|
22185
22224
|
sai_models: 'List the models Sai can run a task with: { models: [{ id, name, provider, tier, costTier, allowed }], default }. `allowed` is per plan (free accounts have an allowlist). Pass an id as sai_task_start.model to switch the session\'s model; "auto" lets Sai pick. Only call this when the user asks for a specific model or a task needs a stronger/faster one.',
|
|
22186
22225
|
sai_task_start: `Send a task to Sai, an autonomous computer-use agent that operates a real Windows/macOS desktop (browser, apps, files) on the chosen machine. Use it for work that needs a screen or the user's logged-in accounts, e.g. "Log in to the vendor portal and list last month's invoices with totals" or "Follow this bug report in Chrome and describe what happens at each step". Returns { session_id, machine_id, queued, push, watch_url? } immediately; the task keeps running on the machine. watch_url is a local page where the user can watch the computer live and approve steps: always give it to the user as a clickable link (some apps can only show the screen there). Then call sai_task_wait with session_id until status is not "running" \u2014 UNLESS push is true, in which case do NOT call sai_task_wait: the result arrives as a channel notification and you should continue with other work. One conversation per machine persists on the "api" channel across calls (Sai remembers earlier tasks and their results); pass new_session: true to start clean. queued: true means Sai was busy and the message was parked as a steer for the running task. ` + NO_SCREENSHOT,
|
|
22187
22226
|
sai_task_wait: `Block up to timeout_s (default ${WAIT_DEFAULT_S}, max ${WAIT_MAX_S}) for the task to leave the "running" state. Returns { status, events, text, approval?, usage?, sessionUsage?, cursor, error? }. usage is this task's model tokens and cost so far (inputTokens, outputTokens, cacheReadTokens, costUsd, byModel); sessionUsage is the same across the session's tasks. status: "running" = timed out, call again passing the returned cursor; "needs_approval" = Sai is paused on \`approval\` \u2014 if approval.isLinkOnly is false decide with sai_task_approve, if true give approval.approvalUrl to the human and call sai_task_wait again; "idle" = done, \`text\` is Sai's answer; "error" = failed, see \`error\`. \`text\` is the assistant text of the whole turn so far; \`events\` are only the frames since \`cursor\`. ` + NO_SCREENSHOT,
|
|
22188
22227
|
sai_task_approve: 'Resolve a pending approval from a needs_approval result. decision: approve | approve_for_task | deny. For approvalType "choice" pass `selections` with the chosen option values. Returns { ok: true } or, when the approval can only be completed by a human in a browser (OAuth consent, credentials, phone verification), { ok: false, reason: "link_only", approval_url } \u2014 hand approval_url to the human, then keep waiting. Only approve actions the user has actually asked for; when in doubt, ask the human.',
|
|
22189
22228
|
sai_task_abort: "Stop the task running in this session. Returns { ok, aborted, reason? }; aborted: false with a reason means nothing was running. Safe to call twice.",
|
|
22190
22229
|
sai_upload: "Upload a local file (max 25 MB) so Sai can use it. Returns { file_id, name, mime, size }; pass file_id in sai_task_start.file_ids. The uploaded file lands in the machine's Sai files, not at the original path.",
|
|
22230
|
+
sai_learn: 'Turn the last task in a session into Simulang code the user owns: `async function main(params = { ... })`, with the inputs found in the task (a site, a name, a date) as parameters. The code runs again without the agent, faster and cheaper. The task must have been started with record_trajectory: true and be finished (sai_task_wait status "idle"). Returns the learn result: { learnId, status, title, template, parameters, code, validation, usage }. Writing the code can take a few minutes: when this returns { status: "running" }, call sai_learn again with the same arguments to keep waiting on the same request. Save `code` to a file when the user asks. To run it, open direct control and run the code with `await main({ ... })` as the last line of the block. Research preview.',
|
|
22191
22231
|
sai_live_link: "A link to the machine's screen for a person: { machine_id, live_url, expires_at } (expires_at in epoch ms). Anyone with live_url can open it in a browser without a Simular sign-in, and can use the mouse and keyboard while no Sai task is running. Call it when Sai needs the person to act on the screen (sign in, solve a captcha, enter a code): give them live_url as a clickable link, and once they say they are done, send Sai a message with sai_task_start to continue. The link carries its own token: give it only to the person who should act. The machine must be running."
|
|
22192
22232
|
};
|
|
22193
22233
|
var serverInstructions = [
|
|
22194
22234
|
"Sai is an autonomous computer-use agent that operates a real desktop (browser, native apps, files, email) on the user's Sai machine.",
|
|
22195
22235
|
"Use it when the work needs a screen: sites and apps with no API (vendor portals, admin consoles, legacy web apps), web apps behind the user's logins (sign-ins go to the human as an approval link), desktop software on Windows, macOS or Linux, or seeing what a real user sees (testing a sign-up flow, reproducing a bug). Don't use it for what you can do locally or through an API.",
|
|
22196
22236
|
'For a workflow the user will repeat, ask Sai after the first run to save it as a replayable skill with parameters ("Save this as a replayable skill named invoice_export, with vendor and month as parameters"); later, ask Sai to run that skill. Sai replays it as code, asking the model only where the screen matters, and the agent takes over if the UI changed.',
|
|
22237
|
+
"When the user wants the code itself (to keep, read or run without the agent): sai_task_start with record_trajectory: true, sai_task_wait until idle, then sai_learn { session_id }. sai_learn returns the code.",
|
|
22197
22238
|
"",
|
|
22198
22239
|
"The loop:",
|
|
22199
22240
|
"1. sai_machines once (skip when you already know the machine_id).",
|
|
@@ -22234,12 +22275,16 @@ function machinesResult(rows) {
|
|
|
22234
22275
|
...m.kind !== void 0 && { kind: m.kind },
|
|
22235
22276
|
...m.online !== void 0 && { online: m.online },
|
|
22236
22277
|
...m.state !== void 0 && { state: m.state },
|
|
22278
|
+
...m.os !== void 0 && { os: m.os },
|
|
22237
22279
|
// Pre-A4 servers send `status` instead of `online`; pass it through rather than guess.
|
|
22238
22280
|
...m.online === void 0 && m.status !== void 0 && { status: m.status }
|
|
22239
22281
|
}));
|
|
22240
22282
|
const only = machines.length === 1 ? machines[0] : void 0;
|
|
22241
22283
|
return { machines, ...only && { default: only.machineId } };
|
|
22242
22284
|
}
|
|
22285
|
+
function timeout(ms) {
|
|
22286
|
+
return new Promise((resolve3) => setTimeout(() => resolve3(void 0), ms).unref?.());
|
|
22287
|
+
}
|
|
22243
22288
|
var SaiTools = class {
|
|
22244
22289
|
constructor(ctx) {
|
|
22245
22290
|
this.ctx = ctx;
|
|
@@ -22247,6 +22292,11 @@ var SaiTools = class {
|
|
|
22247
22292
|
ctx;
|
|
22248
22293
|
/** Uploads made in this process, keyed by fileId — `/message` needs the full attachment row. */
|
|
22249
22294
|
uploads = /* @__PURE__ */ new Map();
|
|
22295
|
+
/**
|
|
22296
|
+
* Learn calls not yet handed to the agent, by request body. A call that outlives one tool call
|
|
22297
|
+
* keeps running here, and the next sai_learn with the same arguments waits on it.
|
|
22298
|
+
*/
|
|
22299
|
+
learning = /* @__PURE__ */ new Map();
|
|
22250
22300
|
async machines() {
|
|
22251
22301
|
return machinesResult(await this.ctx.api.machines());
|
|
22252
22302
|
}
|
|
@@ -22282,7 +22332,8 @@ var SaiTools = class {
|
|
|
22282
22332
|
message: args.task,
|
|
22283
22333
|
...attachments && attachments.length > 0 && { attachments },
|
|
22284
22334
|
...args.model && { model: args.model },
|
|
22285
|
-
...args.autonomous && { autonomous: true }
|
|
22335
|
+
...args.autonomous && { autonomous: true },
|
|
22336
|
+
...args.record_trajectory && { recordTrajectory: true }
|
|
22286
22337
|
});
|
|
22287
22338
|
if (this.ctx.push) this.ctx.onSessionStarted?.(started.sessionId);
|
|
22288
22339
|
return {
|
|
@@ -22338,6 +22389,35 @@ var SaiTools = class {
|
|
|
22338
22389
|
throw err;
|
|
22339
22390
|
}
|
|
22340
22391
|
}
|
|
22392
|
+
async learn(args, waitMs = WAIT_MAX_S * 1e3) {
|
|
22393
|
+
const turnId = this.ctx.source.turnId(args.session_id);
|
|
22394
|
+
if (!turnId) {
|
|
22395
|
+
throw new Error(
|
|
22396
|
+
`No recorded task in session ${args.session_id} from this MCP server process. Run the task with sai_task_start { record_trajectory: true }, wait until it is idle, then call sai_learn.`
|
|
22397
|
+
);
|
|
22398
|
+
}
|
|
22399
|
+
const body = {
|
|
22400
|
+
turns: [turnId],
|
|
22401
|
+
...args.task_template && { taskTemplate: args.task_template },
|
|
22402
|
+
...args.guidance && { guidance: args.guidance }
|
|
22403
|
+
};
|
|
22404
|
+
const key = JSON.stringify(body);
|
|
22405
|
+
let call = this.learning.get(key);
|
|
22406
|
+
if (!call) {
|
|
22407
|
+
call = this.ctx.api.learn(body);
|
|
22408
|
+
this.learning.set(key, call);
|
|
22409
|
+
call.catch(() => this.learning.delete(key));
|
|
22410
|
+
}
|
|
22411
|
+
const result = await Promise.race([call, timeout(waitMs)]);
|
|
22412
|
+
if (!result) {
|
|
22413
|
+
return {
|
|
22414
|
+
status: "running",
|
|
22415
|
+
message: "Still writing the code. Call sai_learn again with the same arguments to keep waiting."
|
|
22416
|
+
};
|
|
22417
|
+
}
|
|
22418
|
+
this.learning.delete(key);
|
|
22419
|
+
return result;
|
|
22420
|
+
}
|
|
22341
22421
|
async liveLink(args) {
|
|
22342
22422
|
const machineId2 = await this.resolveMachineId(args.machine_id);
|
|
22343
22423
|
const live = await this.ctx.api.liveScreen(machineId2);
|
|
@@ -22379,9 +22459,12 @@ var EXEC_DEFAULT_S = 90;
|
|
|
22379
22459
|
var EXEC_MAX_S = 110;
|
|
22380
22460
|
var SIMULANG_REFERENCE = `# Simulang in Sai direct control
|
|
22381
22461
|
|
|
22382
|
-
Direct control is a JavaScript REPL running ON one
|
|
22462
|
+
Direct control is a JavaScript REPL running ON one of the user's computers: a Sai cloud computer
|
|
22463
|
+
(Windows, Linux or macOS) or the user's own Mac or Windows PC with the Sai Agent.
|
|
22383
22464
|
Top-level await works and variables persist between blocks (use \`var\`).
|
|
22384
22465
|
The block's last expression is returned. console.log output comes back in \`logs\`.
|
|
22466
|
+
\`new Date()\` reads the account's clock (the timezone the user's Sai app reported, else UTC), the same clock
|
|
22467
|
+
learn jobs test code on; use \`toISOString()\` or \`getUTC*\` for UTC.
|
|
22385
22468
|
|
|
22386
22469
|
## The machine: \`machine\` (already held by your control lease)
|
|
22387
22470
|
Shell and files:
|
|
@@ -22420,12 +22503,14 @@ Refs come from the LATEST snapshot: snapshot, act, snapshot again.
|
|
|
22420
22503
|
|
|
22421
22504
|
## Also
|
|
22422
22505
|
await wait({ waitTime: 2 }) seconds (unit: 'ms' for milliseconds)
|
|
22506
|
+
callLLM({ prompt, context? }) \u2192 a model's answer as a string (context: { text?, imageBase64? }); billed to the account
|
|
22507
|
+
showMessageToUser({ message }) writes "[message] ..." to logs
|
|
22423
22508
|
$lastVisualObservation, $lastAccessibilityObservation, $lastExec
|
|
22424
22509
|
|
|
22425
|
-
Not available in direct control: sai.*, integrations (google, slack, \u2026),
|
|
22510
|
+
Not available in direct control: sai.*, integrations (google, slack, \u2026), askUser, askChoice,
|
|
22426
22511
|
requestApproval, generateImage, secrets. Do those from your own program.
|
|
22427
22512
|
`;
|
|
22428
|
-
var machineId = external_exports.string().min(1).describe("
|
|
22513
|
+
var machineId = external_exports.string().min(1).describe("A computer from sai_machines, cloud or the user's own.");
|
|
22429
22514
|
var controlToolSchemas = {
|
|
22430
22515
|
sai_control_open: { machine_id: machineId },
|
|
22431
22516
|
sai_control_exec: {
|
|
@@ -22443,7 +22528,7 @@ var controlToolSchemas = {
|
|
|
22443
22528
|
}
|
|
22444
22529
|
};
|
|
22445
22530
|
var controlToolDescriptions = {
|
|
22446
|
-
sai_control_open:
|
|
22531
|
+
sai_control_open: `Take direct control of one of the user's computers (a Sai cloud computer, or their own Mac or PC with the Sai Agent) so YOU can drive it by running Simulang (JavaScript) blocks with sai_control_exec. On the user's own computer (kind "own") the blocks use their real screen, mouse and keyboard, and the user must first turn this on from a signed-in session; until then it fails with own_computer_access_off, whose message says how. Use this instead of sai_task_start when you want step-by-step control, or want to write a script you can replay. Returns { machine_id, expires_after_idle_s }. Control holds the computer: Sai tasks on it wait until you close it. Calling it again while control is open is fine and returns at once. Can take up to ~2 minutes while the computer starts. Read sai://simulang/reference for the API.`,
|
|
22447
22532
|
sai_control_exec: "Run one Simulang block on the computer you control. Returns { result, logs, error?, variables, duration_ms } and, when the block took a screenshot (machine.pageContent(), page/app snapshot or screenshot()), that screenshot as an image. Variables persist between blocks (use `var`). Prefer page.snapshot()/app.snapshot() refs over pixel clicks. error.kind: exception | timeout | interrupted. If control has ended (closed, idle, taken by a Sai task, or the computer stopped answering) it fails with 410 control_closed and a reason: call sai_control_open again for a fresh lease.\n\nQuick reference: `await machine.exec({ command })`, `var page = await machine.browser.newtab(url)`, `var snap = await page.snapshot(); snap.snapshot.outline()`, `await page.click({ ref })`, `await machine.pageContent()`, `await machine.ground({ concept })` \u2192 { x, y }, `await machine.click({ x, y })`. Full API: resource sai://simulang/reference.",
|
|
22448
22533
|
sai_control_interrupt: "Stop the running block (it ends at its next primitive call or loop iteration). Returns { interrupted }; false means nothing was running.",
|
|
22449
22534
|
sai_control_close: "Release the computer: resets the REPL and frees the computer for Sai tasks. Always close when you are done."
|
|
@@ -22694,7 +22779,7 @@ var TASK_VIEW_TOOL_META = {
|
|
|
22694
22779
|
"ui/resourceUri": TASK_VIEW_URI
|
|
22695
22780
|
};
|
|
22696
22781
|
function taskViewHtml() {
|
|
22697
|
-
return true ? '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="utf-8" />\n <meta name="viewport" content="width=device-width, initial-scale=1" />\n <title>Sai task</title>\n <style>\n :root {\n --bg: #fff;\n --fg: #1b1b1b;\n --muted: #6b6b6b;\n --line: #e5e5e5;\n --card: #f6f6f4;\n --accent: #1b1b1b;\n --accent-fg: #fff;\n --ok: #2f9e44;\n --warn: #e8a317;\n --err: #d64545;\n }\n @media (prefers-color-scheme: dark) {\n :root:not([data-theme=\'light\']) {\n --bg: #161616;\n --fg: #eee;\n --muted: #9a9a9a;\n --line: #2c2c2c;\n --card: #1f1f1f;\n --accent: #eee;\n --accent-fg: #111;\n }\n }\n :root[data-theme=\'dark\'] {\n --bg: #161616;\n --fg: #eee;\n --muted: #9a9a9a;\n --line: #2c2c2c;\n --card: #1f1f1f;\n --accent: #eee;\n --accent-fg: #111;\n }\n * {\n box-sizing: border-box;\n }\n body {\n margin: 0;\n padding: 14px 16px;\n font:\n 13.5px/1.5 system-ui,\n -apple-system,\n sans-serif;\n color: var(--fg);\n background: var(--bg);\n }\n header {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .brand {\n font-weight: 600;\n }\n .modes {\n margin-left: auto;\n display: flex;\n gap: 6px;\n }\n button.mode {\n padding: 2px 8px;\n font-size: 12px;\n }\n /* Picture-in-picture: just the screen, the status and any approval. */\n [data-mode=\'pip\'] #steps,\n [data-mode=\'pip\'] #steps-more,\n [data-mode=\'pip\'] #answer,\n [data-mode=\'pip\'] #live {\n display: none;\n }\n [data-mode=\'pip\'] body {\n padding: 8px 10px;\n }\n #headline {\n color: var(--muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n }\n .dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--muted);\n flex: none;\n }\n .dot.running,\n .dot.starting {\n background: var(--ok);\n animation: pulse 1.2s ease-in-out infinite;\n }\n .dot.needs_approval {\n background: var(--warn);\n }\n .dot.error {\n background: var(--err);\n }\n @keyframes pulse {\n 50% {\n opacity: 0.35;\n }\n }\n ol {\n margin: 10px 0 0;\n padding-left: 20px;\n color: var(--muted);\n }\n ol li:last-child {\n color: var(--fg);\n }\n #steps-more {\n color: var(--muted);\n font-size: 12px;\n margin-top: 4px;\n }\n .card {\n margin-top: 12px;\n padding: 10px 12px;\n border: 1px solid var(--line);\n border-radius: 10px;\n background: var(--card);\n }\n #approval-text,\n #answer,\n #error {\n white-space: pre-wrap;\n }\n #error {\n border-color: var(--err);\n }\n .row {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 8px;\n }\n button {\n font: inherit;\n padding: 5px 10px;\n border-radius: 7px;\n border: 1px solid var(--line);\n background: var(--bg);\n color: var(--fg);\n cursor: pointer;\n }\n button.primary {\n background: var(--accent);\n color: var(--accent-fg);\n border-color: var(--accent);\n }\n #live {\n margin-top: 12px;\n }\n /* Opened in a browser tab rather than inside a host\'s chat. */\n .standalone body {\n max-width: 960px;\n margin: 24px auto;\n }\n #answer code {\n font:\n 12px ui-monospace,\n SFMono-Regular,\n Menlo,\n monospace;\n padding: 1px 4px;\n border-radius: 4px;\n background: var(--line);\n }\n #steps .detail {\n display: block;\n color: var(--muted);\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n #screen-wrap {\n margin-top: 10px;\n }\n /* Guacamole sizes its own layers; the box keeps 16:9 before the first frame. */\n #screen {\n width: 100%;\n aspect-ratio: 16 / 9;\n background: #0b0d12;\n border-radius: 8px;\n overflow: hidden;\n }\n #screen img {\n width: 100%;\n display: block;\n }\n #screen-note {\n margin-top: 4px;\n color: var(--muted);\n font-size: 12px;\n }\n </style>\n </head>\n <body>\n <header>\n <span id="dot" class="dot starting"></span><span class="brand">Sai</span\n ><span id="headline">Starting Sai\u2026</span>\n <span class="modes">\n <button id="pin" class="mode" hidden title="Keep this view on screen while you scroll">\n Keep visible\n </button>\n <button id="expand" class="mode" hidden title="Open full screen">Expand</button>\n <button\n id="popout"\n class="mode"\n hidden\n title="Watch in its own window while you keep chatting"\n >\n Open in a window \u2197\n </button>\n <button id="restore" class="mode" hidden title="Back into the conversation">\n Back to chat\n </button>\n </span>\n </header>\n <div id="screen-wrap" hidden>\n <div id="screen"></div>\n <div id="screen-note" hidden></div>\n <button id="watch-here" hidden title="Take the live screen back to this view">\n Watch here\n </button>\n </div>\n <ol id="steps"></ol>\n <div id="steps-more"></div>\n <div id="approval" class="card" hidden>\n <strong id="approval-title"></strong>\n <div id="approval-text"></div>\n <div class="row">\n <button id="approve" class="primary">Approve</button>\n <button id="approve-task">Approve for this task</button>\n <button id="deny">Deny</button>\n <button id="open-approval" class="primary" hidden>Open to finish</button>\n </div>\n </div>\n <div id="error" class="card" hidden></div>\n <div id="answer" class="card" hidden></div>\n <button id="live" hidden>Open in the Playground \u2197</button>\n <script>\n "use strict";(()=>{function Ee(r){try{return["http:","https:"].includes(new URL(r).protocol)}catch{return!1}}var ae=class{constructor(e=window.parent){this.host=e;window.addEventListener("message",t=>this.receive(t))}host;nextId=1;pending=new Map;onToolInput;onToolResult;onHostContext;receive(e){if(e.source!==this.host)return;let t=e.data;if(!t||t.jsonrpc!=="2.0")return;if(typeof t.id=="number"&&("result"in t||"error"in t)){let s=this.pending.get(t.id);if(!s)return;this.pending.delete(t.id);let o=t.error;o?s.reject(new Error(o.message??"Host error")):s.resolve(t.result);return}let a=t.params??{};t.method==="ui/notifications/tool-input"?this.onToolInput?.(a.arguments??{}):t.method==="ui/notifications/tool-result"?this.onToolResult?.(a):t.method==="ui/notifications/host-context-changed"&&this.onHostContext?.(a),t.id!==void 0&&typeof t.method=="string"&&this.host.postMessage({jsonrpc:"2.0",id:t.id,result:{}},"*")}request(e,t){let a=this.nextId++;return new Promise((s,o)=>{this.pending.set(a,{resolve:s,reject:o}),this.host.postMessage({jsonrpc:"2.0",id:a,method:e,params:t},"*")})}notify(e,t){this.host.postMessage({jsonrpc:"2.0",method:e,params:t},"*")}async connect(e){let t=await this.request("ui/initialize",{protocolVersion:"2026-01-26",appInfo:{name:"Sai task",version:e},appCapabilities:{availableDisplayModes:["inline","pip","fullscreen"]}});return this.notify("ui/notifications/initialized",{}),t}async callTool(e,t){return await this.request("tools/call",{name:e,arguments:t})}openLink(e){Ee(e)&&this.request("ui/open-link",{url:e}).catch(()=>{})}async requestDisplayMode(e){return(await this.request("ui/request-display-mode",{mode:e})).mode??e}sizeChanged(e){this.notify("ui/notifications/size-changed",{width:document.body.scrollWidth,height:e})}},oe=class{onToolInput;onToolResult;onHostContext;params=new URLSearchParams(location.search);token=this.params.get("t")??"";async connect(e){let t=this.params.get("s"),a=this.params.get("m"),s=this.params.get("k");return t&&queueMicrotask(()=>this.onToolResult?.({structuredContent:{session_id:t,...a&&{machine_id:a},...s&&{task_id:s}}})),{}}async callTool(e,t){let a=await fetch("/tool",{method:"POST",headers:{"Content-Type":"application/json","x-sai-token":this.token},body:JSON.stringify({name:e,arguments:t})});return a.ok?await a.json():{isError:!0,content:[{type:"text",text:`HTTP ${a.status}`}]}}openLink(e){Ee(e)&&window.open(e,"_blank","noopener,noreferrer")}async requestDisplayMode(e){return"inline"}sizeChanged(e){}};var n=n||{};n.ArrayBufferReader=function(r){var e=this;r.onblob=function(t){var a,s;if(Uint8Array.fromBase64)s=Uint8Array.fromBase64(t),a=s.buffer;else{var o=window.atob(t);a=new ArrayBuffer(o.length),s=new Uint8Array(a);for(var d=0;d<o.length;d++)s[d]=o.charCodeAt(d)}e.ondata&&e.ondata(a)},r.onend=function(){e.onend&&e.onend()},this.ondata=null,this.onend=null};var n=n||{};n.ArrayBufferWriter=function(r){var e=this;r.onack=function(a){e.onack&&e.onack(a)};function t(a){for(var s="",o=0;o<a.byteLength;o++)s+=String.fromCharCode(a[o]);r.sendBlob(window.btoa(s))}this.blobLength=n.ArrayBufferWriter.DEFAULT_BLOB_LENGTH,this.sendData=function(a){var s=new Uint8Array(a);if(s.length<=e.blobLength)t(s);else for(var o=0;o<s.length;o+=e.blobLength)t(s.subarray(o,o+e.blobLength))},this.sendEnd=function(){r.sendEnd()},this.onack=null};n.ArrayBufferWriter.DEFAULT_BLOB_LENGTH=6048;var n=n||{};n.AudioContextFactory={singleton:null,getAudioContext:function(){var e=window.AudioContext||window.webkitAudioContext;if(e)try{return n.AudioContextFactory.singleton||(n.AudioContextFactory.singleton=new e),n.AudioContextFactory.singleton}catch{}return null}};var n=n||{};n.AudioPlayer=function(){this.sync=function(){}};n.AudioPlayer.isSupportedType=function(e){return n.RawAudioPlayer.isSupportedType(e)};n.AudioPlayer.getSupportedTypes=function(){return n.RawAudioPlayer.getSupportedTypes()};n.AudioPlayer.getInstance=function(e,t){return n.RawAudioPlayer.isSupportedType(t)?new n.RawAudioPlayer(e,t):null};n.RawAudioPlayer=function(e,t){var a=n.RawAudioFormat.parse(t),s=n.AudioContextFactory.getAudioContext(),o=s.currentTime,d=new n.ArrayBufferReader(e),c=.02,x=.3,u=a.bytesPerSample===1?window.Int8Array:window.Int16Array,y=a.bytesPerSample===1?128:32768,w=[],T=function(v){if(v.length<=1)return v[0];var g=0;v.forEach(function(R){g+=R.length});var p=0,m=new u(g);return v.forEach(function(R){m.set(R,p),p+=R.length}),m},k=function(v){for(var g=Number.MAX_VALUE,p=v.length,m=Math.floor(v.length/a.channels),S=Math.floor(a.rate*c),R=Math.max(a.channels*S,a.channels*(m-S)),M=R;M<v.length;M+=a.channels){for(var O=0,F=0;F<a.channels;F++)O+=Math.abs(v[M+F]);O<=g&&(p=M+a.channels,g=O)}return p===v.length?[v]:[new u(v.buffer.slice(0,p*a.bytesPerSample)),new u(v.buffer.slice(p*a.bytesPerSample))]},_=function(v){w.push(new u(v))},P=function(){var v=T(w);return v?(w=k(v),v=w.shift(),v):null},b=function(v){var g=v.length/a.channels,p=s.currentTime;o<p&&(o=p);for(var m=s.createBuffer(a.channels,g,a.rate),S=0;S<a.channels;S++)for(var R=m.getChannelData(S),M=S,O=0;O<g;O++)R[O]=v[M]/y,M+=a.channels;return m};d.ondata=function(v){_(new u(v));var g=P();if(g){var p=s.currentTime;o<p&&(o=p);var m=s.createBufferSource();m.connect(s.destination),m.start||(m.start=m.noteOn),m.buffer=b(g),m.start(o),o+=g.length/a.channels/a.rate}},this.sync=function(){var v=s.currentTime;o=Math.min(o,v+x)}};n.RawAudioPlayer.prototype=new n.AudioPlayer;n.RawAudioPlayer.isSupportedType=function(e){return n.AudioContextFactory.getAudioContext()?n.RawAudioFormat.parse(e)!==null:!1};n.RawAudioPlayer.getSupportedTypes=function(){return n.AudioContextFactory.getAudioContext()?["audio/L8","audio/L16"]:[]};var n=n||{};n.AudioRecorder=function(){this.onclose=null,this.onerror=null};n.AudioRecorder.isSupportedType=function(e){return n.RawAudioRecorder.isSupportedType(e)};n.AudioRecorder.getSupportedTypes=function(){return n.RawAudioRecorder.getSupportedTypes()};n.AudioRecorder.getInstance=function(e,t){return n.RawAudioRecorder.isSupportedType(t)?new n.RawAudioRecorder(e,t):null};n.RawAudioRecorder=function(e,t){var a=this,s=2048,o=3,d=n.RawAudioFormat.parse(t),c=n.AudioContextFactory.getAudioContext();navigator.mediaDevices||(navigator.mediaDevices={}),navigator.mediaDevices.getUserMedia||(navigator.mediaDevices.getUserMedia=(navigator.getUserMedia||navigator.webkitGetUserMedia||navigator.mozGetUserMedia||navigator.msGetUserMedia).bind(navigator));var x=new n.ArrayBufferWriter(e),u=d.bytesPerSample===1?window.Int8Array:window.Int16Array,y=d.bytesPerSample===1?128:32768,w=0,T=0,k=null,_=null,P=null,b=function(O){if(O===0)return 1;var F=Math.PI*O;return Math.sin(F)/F},l=function(O,F){return-F<O&&O<F?b(O)*b(O/F):0},v=function(O,F){for(var H=(O.length-1)*F,i=Math.floor(H)-o+1,f=Math.floor(H)+o,h=0,C=i;C<=f;C++)h+=(O[C]||0)*l(H-C,o);return h},g=function(O){var F=O.length;w+=F;var H=Math.round(w*d.rate/O.sampleRate),i=H-T;T+=i;for(var f=new u(i*d.channels),h=0;h<d.channels;h++)for(var C=O.getChannelData(h),A=h,L=0;L<i;L++)f[A]=v(C,L/(i-1))*y,A+=d.channels;return f},p=function(O){P=c.createScriptProcessor(s,d.channels,d.channels),P.connect(c.destination),P.onaudioprocess=function(H){x.sendData(g(H.inputBuffer).buffer)},_=c.createMediaStreamSource(O),_.connect(P),c.state==="suspended"&&c.resume(),k=O},m=function(){x.sendEnd(),a.onerror&&a.onerror()},S=function(){var O=navigator.mediaDevices.getUserMedia({audio:!0},p,m);O&&O.then&&O.then(p,m)},R=function(){if(_&&_.disconnect(),P&&P.disconnect(),k)for(var O=k.getTracks(),F=0;F<O.length;F++)O[F].stop();P=null,_=null,k=null,x.sendEnd()};x.onack=function(O){O.code===n.Status.Code.SUCCESS&&!k?S():(R(),x.onack=null,O.code===n.Status.Code.RESOURCE_CLOSED?a.onclose&&a.onclose():a.onerror&&a.onerror())}};n.RawAudioRecorder.prototype=new n.AudioRecorder;n.RawAudioRecorder.isSupportedType=function(e){return n.AudioContextFactory.getAudioContext()?n.RawAudioFormat.parse(e)!==null:!1};n.RawAudioRecorder.getSupportedTypes=function(){return n.AudioContextFactory.getAudioContext()?["audio/L8","audio/L16"]:[]};var n=n||{};n.BlobReader=function(r,e){var t=this,a=0,s;window.BlobBuilder?s=new BlobBuilder:window.WebKitBlobBuilder?s=new WebKitBlobBuilder:window.MozBlobBuilder?s=new MozBlobBuilder:s=new(function(){var o=[];this.append=function(d){o.push(new Blob([d],{type:e}))},this.getBlob=function(){return new Blob(o,{type:e})}}),r.onblob=function(o){for(var d=window.atob(o),c=new ArrayBuffer(d.length),x=new Uint8Array(c),u=0;u<d.length;u++)x[u]=d.charCodeAt(u);s.append(c),a+=c.byteLength,t.onprogress&&t.onprogress(c.byteLength),r.sendAck("OK",0)},r.onend=function(){t.onend&&t.onend()},this.getLength=function(){return a},this.getBlob=function(){return s.getBlob()},this.onprogress=null,this.onend=null};var n=n||{};n.BlobWriter=function(e){var t=this,a=new n.ArrayBufferWriter(e);a.onack=function(o){t.onack&&t.onack(o)};var s=function(d,c,x){var u=(d.slice||d.webkitSlice||d.mozSlice).bind(d),y=x-c;if(y!==x){var w=u(c,y);if(w.size===y)return w}return u(c,x)};this.sendBlob=function(d){var c=0,x=function u(){if(c>=d.size){t.oncomplete&&t.oncomplete(d);return}var y=s(d,c,c+a.blobLength);c+=a.blobLength;var w=new FileReader;w.onload=function(){a.sendData(w.result),a.onack=function(_){t.onack&&t.onack(_),!_.isError()&&(t.onprogress&&t.onprogress(d,c-a.blobLength),u())}},w.onerror=function(){t.onerror&&t.onerror(d,c,w.error)},w.readAsArrayBuffer(y)};x()},this.sendEnd=function(){a.sendEnd()},this.onack=null,this.onerror=null,this.onprogress=null,this.oncomplete=null};var n=n||{};n.Client=function(r){var e=this,t=n.Client.State.IDLE,a=0,s=5e3,o=null,d=0,c={0:"butt",1:"round",2:"square"},x={0:"bevel",1:"miter",2:"round"},u=new n.Display,y={},w={},T={},k=[],_=[],P=[],b=new n.IntegerPool,l=[];function v(i){i!=t&&(t=i,e.onstatechange&&e.onstatechange(t))}function g(){return t==n.Client.State.CONNECTED||t==n.Client.State.WAITING}this.exportState=function(f){var h={currentState:t,currentTimestamp:a,layers:{}},C={};for(var A in y)C[A]=y[A];u.flush(function(){for(var I in C){var E=parseInt(I),D=C[I],B={width:D.width,height:D.height};if(D.width&&D.height){var Y=D.toCanvas();B.url=Y.toDataURL("image/png")}E>0&&(B.x=D.x,B.y=D.y,B.z=D.z,B.alpha=D.alpha,B.matrix=D.matrix,B.parent=m(D.parent)),h.layers[I]=B}f(h)})},this.importState=function(f,h){var C,A;t=f.currentState,a=f.currentTimestamp,u.cancel();for(C in y)A=parseInt(C),A>0&&y[C].dispose();y={};for(C in f.layers){A=parseInt(C);var L=f.layers[C],I=p(A);if(u.resize(I,L.width,L.height),L.url&&(u.setChannelMask(I,n.Layer.SRC),u.draw(I,0,0,L.url)),A>0&&L.parent>=0){var E=p(L.parent);u.move(I,E,L.x,L.y,L.z),u.shade(I,L.alpha);var D=L.matrix;u.distort(I,D[0],D[1],D[2],D[3],D[4],D[5])}}u.flush(h)},this.getDisplay=function(){return u},this.sendSize=function(i,f){g()&&r.sendMessage("size",i,f)},this.sendKeyEvent=function(i,f){g()&&r.sendMessage("key",f,i)},this.sendMouseState=function(f,h){if(g()){var C=f.x,A=f.y;h&&(C/=u.getScale(),A/=u.getScale()),u.moveCursor(Math.floor(C),Math.floor(A));var L=0;f.left&&(L|=1),f.middle&&(L|=2),f.right&&(L|=4),f.up&&(L|=8),f.down&&(L|=16),r.sendMessage("mouse",Math.floor(C),Math.floor(A),L)}},this.sendTouchState=function(f,h){if(g()){var C=f.x,A=f.y;h&&(C/=u.getScale(),A/=u.getScale()),r.sendMessage("touch",f.id,Math.floor(C),Math.floor(A),Math.floor(f.radiusX),Math.floor(f.radiusY),f.angle,f.force)}},this.createOutputStream=function(){var f=b.next(),h=l[f]=new n.OutputStream(e,f);return h},this.createAudioStream=function(i){var f=e.createOutputStream();return r.sendMessage("audio",f.index,i),f},this.createFileStream=function(i,f){var h=e.createOutputStream();return r.sendMessage("file",h.index,i,f),h},this.createPipeStream=function(i,f){var h=e.createOutputStream();return r.sendMessage("pipe",h.index,i,f),h},this.createClipboardStream=function(i){var f=e.createOutputStream();return r.sendMessage("clipboard",f.index,i),f},this.createArgumentValueStream=function(f,h){var C=e.createOutputStream();return r.sendMessage("argv",C.index,f,h),C},this.createObjectOutputStream=function(f,h,C){var A=e.createOutputStream();return r.sendMessage("put",f,A.index,h,C),A},this.requestObjectInputStream=function(f,h){g()&&r.sendMessage("get",f,h)},this.sendAck=function(i,f,h){g()&&r.sendMessage("ack",i,f,h)},this.sendBlob=function(i,f){g()&&r.sendMessage("blob",i,f)},this.endStream=function(i){g()&&(r.sendMessage("end",i),l[i]&&(b.free(i),delete l[i]))},this.onstatechange=null,this.onname=null,this.onerror=null,this.onmsg=null,this.onjoin=null,this.onleave=null,this.onaudio=null,this.onvideo=null,this.onmultitouch=null,this.onargv=null,this.onclipboard=null,this.onfile=null,this.onfilesystem=null,this.onpipe=null,this.onrequired=null,this.onsync=null;var p=function(f){var h=y[f];return h||(f===0?h=u.getDefaultLayer():f>0?h=u.createLayer():h=u.createBuffer(),y[f]=h),h},m=function(f){if(!f)return null;for(var h in y)if(f===y[h])return parseInt(h);return null};function S(i){var f=k[i];return f==null&&(f=k[i]=new n.Parser,f.oninstruction=r.oninstruction),f}var R={"miter-limit":function(i,f){u.setMiterLimit(i,parseFloat(f))},"multi-touch":function(f,h){e.onmultitouch&&f instanceof n.Display.VisibleLayer&&e.onmultitouch(f,parseInt(h))}},M={ack:function(i){var f=parseInt(i[0]),h=i[1],C=parseInt(i[2]),A=l[f];A&&(A.onack&&A.onack(new n.Status(C,h)),C>=256&&l[f]===A&&(b.free(f),delete l[f]))},arc:function(i){var f=p(parseInt(i[0])),h=parseInt(i[1]),C=parseInt(i[2]),A=parseInt(i[3]),L=parseFloat(i[4]),I=parseFloat(i[5]),E=parseInt(i[6]);u.arc(f,h,C,A,L,I,E!=0)},argv:function(i){var f=parseInt(i[0]),h=i[1],C=i[2];if(e.onargv){var A=_[f]=new n.InputStream(e,f);e.onargv(A,h,C)}else e.sendAck(f,"Receiving argument values unsupported",256)},audio:function(i){var f=parseInt(i[0]),h=i[1],C=_[f]=new n.InputStream(e,f),A=null;e.onaudio&&(A=e.onaudio(C,h)),A||(A=n.AudioPlayer.getInstance(C,h)),A?(w[f]=A,e.sendAck(f,"OK",0)):e.sendAck(f,"BAD TYPE",783)},blob:function(i){var f=parseInt(i[0]),h=i[1],C=_[f];C&&C.onblob&&C.onblob(h)},body:function(f){var h=parseInt(f[0]),C=P[h],A=parseInt(f[1]),L=f[2],I=f[3];if(C&&C.onbody){var E=_[A]=new n.InputStream(e,A);C.onbody(E,L,I)}else e.sendAck(A,"Receipt of body unsupported",256)},cfill:function(i){var f=parseInt(i[0]),h=p(parseInt(i[1])),C=parseInt(i[2]),A=parseInt(i[3]),L=parseInt(i[4]),I=parseInt(i[5]);u.setChannelMask(h,f),u.fillColor(h,C,A,L,I)},clip:function(i){var f=p(parseInt(i[0]));u.clip(f)},clipboard:function(i){var f=parseInt(i[0]),h=i[1];if(e.onclipboard){var C=_[f]=new n.InputStream(e,f);e.onclipboard(C,h)}else e.sendAck(f,"Clipboard unsupported",256)},close:function(i){var f=p(parseInt(i[0]));u.close(f)},copy:function(i){var f=p(parseInt(i[0])),h=parseInt(i[1]),C=parseInt(i[2]),A=parseInt(i[3]),L=parseInt(i[4]),I=parseInt(i[5]),E=p(parseInt(i[6])),D=parseInt(i[7]),B=parseInt(i[8]);u.setChannelMask(E,I),u.copy(f,h,C,A,L,E,D,B)},cstroke:function(i){var f=parseInt(i[0]),h=p(parseInt(i[1])),C=c[parseInt(i[2])],A=x[parseInt(i[3])],L=parseInt(i[4]),I=parseInt(i[5]),E=parseInt(i[6]),D=parseInt(i[7]),B=parseInt(i[8]);u.setChannelMask(h,f),u.strokeColor(h,C,A,L,I,E,D,B)},cursor:function(i){var f=parseInt(i[0]),h=parseInt(i[1]),C=p(parseInt(i[2])),A=parseInt(i[3]),L=parseInt(i[4]),I=parseInt(i[5]),E=parseInt(i[6]);u.setCursor(f,h,C,A,L,I,E)},curve:function(i){var f=p(parseInt(i[0])),h=parseInt(i[1]),C=parseInt(i[2]),A=parseInt(i[3]),L=parseInt(i[4]),I=parseInt(i[5]),E=parseInt(i[6]);u.curveTo(f,h,C,A,L,I,E)},disconnect:function(f){e.disconnect()},dispose:function(i){var f=parseInt(i[0]);if(f>0){var h=p(f);u.dispose(h),delete y[f]}else f<0&&delete y[f]},distort:function(i){var f=parseInt(i[0]),h=parseFloat(i[1]),C=parseFloat(i[2]),A=parseFloat(i[3]),L=parseFloat(i[4]),I=parseFloat(i[5]),E=parseFloat(i[6]);if(f>=0){var D=p(f);u.distort(D,h,C,A,L,I,E)}},error:function(i){var f=i[0],h=parseInt(i[1]);e.onerror&&e.onerror(new n.Status(h,f)),e.disconnect()},end:function(i){var f=parseInt(i[0]),h=_[f];h&&(h.onend&&h.onend(),delete _[f])},file:function(i){var f=parseInt(i[0]),h=i[1],C=i[2];if(e.onfile){var A=_[f]=new n.InputStream(e,f);e.onfile(A,h,C)}else e.sendAck(f,"File transfer unsupported",256)},filesystem:function(f){var h=parseInt(f[0]),C=f[1];if(e.onfilesystem){var A=P[h]=new n.Object(e,h);e.onfilesystem(A,C)}},identity:function(i){var f=p(parseInt(i[0]));u.setTransform(f,1,0,0,1,0,0)},img:function(i){var f=parseInt(i[0]),h=parseInt(i[1]),C=p(parseInt(i[2])),A=i[3],L=parseInt(i[4]),I=parseInt(i[5]),E=_[f]=new n.InputStream(e,f);u.setChannelMask(C,h),u.drawStream(C,L,I,E,A)},jpeg:function(i){var f=parseInt(i[0]),h=p(parseInt(i[1])),C=parseInt(i[2]),A=parseInt(i[3]),L=i[4];u.setChannelMask(h,f),u.draw(h,C,A,"data:image/jpeg;base64,"+L)},lfill:function(i){var f=parseInt(i[0]),h=p(parseInt(i[1])),C=p(parseInt(i[2]));u.setChannelMask(h,f),u.fillLayer(h,C)},line:function(i){var f=p(parseInt(i[0])),h=parseInt(i[1]),C=parseInt(i[2]);u.lineTo(f,h,C)},lstroke:function(i){var f=parseInt(i[0]),h=p(parseInt(i[1])),C=p(parseInt(i[2]));u.setChannelMask(h,f),u.strokeLayer(h,C)},mouse:function(f){var h=parseInt(f[0]),C=parseInt(f[1]);u.showCursor(!0),u.moveCursor(h,C)},move:function(i){var f=parseInt(i[0]),h=parseInt(i[1]),C=parseInt(i[2]),A=parseInt(i[3]),L=parseInt(i[4]);if(f>0&&h>=0){var I=p(f),E=p(h);u.move(I,E,C,A,L)}},msg:function(i){var f,h,C=!0,A=parseInt(i[0]);if(e.onmsg&&(C=e.onmsg(A,i.slice(1)),C===void 0&&(C=!0)),C)switch(A){case n.Client.Message.USER_JOINED:f=i[1],h=i[2],e.onjoin&&e.onjoin(f,h);break;case n.Client.Message.USER_LEFT:f=i[1],h=i[2],e.onleave&&e.onleave(f,h);break}},name:function(i){e.onname&&e.onname(i[0])},nest:function(i){var f=S(parseInt(i[0]));f.receive(i[1])},pipe:function(i){var f=parseInt(i[0]),h=i[1],C=i[2];if(e.onpipe){var A=_[f]=new n.InputStream(e,f);e.onpipe(A,h,C)}else e.sendAck(f,"Named pipes unsupported",256)},png:function(i){var f=parseInt(i[0]),h=p(parseInt(i[1])),C=parseInt(i[2]),A=parseInt(i[3]),L=i[4];u.setChannelMask(h,f),u.draw(h,C,A,"data:image/png;base64,"+L)},pop:function(i){var f=p(parseInt(i[0]));u.pop(f)},push:function(i){var f=p(parseInt(i[0]));u.push(f)},rect:function(i){var f=p(parseInt(i[0])),h=parseInt(i[1]),C=parseInt(i[2]),A=parseInt(i[3]),L=parseInt(i[4]);u.rect(f,h,C,A,L)},required:function(f){e.onrequired&&e.onrequired(f)},reset:function(i){var f=p(parseInt(i[0]));u.reset(f)},set:function(i){var f=p(parseInt(i[0])),h=i[1],C=i[2],A=R[h];A&&A(f,C)},shade:function(i){var f=parseInt(i[0]),h=parseInt(i[1]);if(f>=0){var C=p(f);u.shade(C,h)}},size:function(i){var f=parseInt(i[0]),h=p(f),C=parseInt(i[1]),A=parseInt(i[2]);u.resize(h,C,A)},start:function(i){var f=p(parseInt(i[0])),h=parseInt(i[1]),C=parseInt(i[2]);u.moveTo(f,h,C)},sync:function(i){var f=parseInt(i[0]),h=i[1]?parseInt(i[1]):0;u.flush(function(){for(var A in w){var L=w[A];L&&L.sync()}f!==a&&(r.sendMessage("sync",f),a=f)},f,h),t===n.Client.State.WAITING&&v(n.Client.State.CONNECTED),e.onsync&&e.onsync(f,h)},transfer:function(i){var f=p(parseInt(i[0])),h=parseInt(i[1]),C=parseInt(i[2]),A=parseInt(i[3]),L=parseInt(i[4]),I=parseInt(i[5]),E=p(parseInt(i[6])),D=parseInt(i[7]),B=parseInt(i[8]);I===3?u.put(f,h,C,A,L,E,D,B):I!==5&&u.transfer(f,h,C,A,L,E,D,B,n.Client.DefaultTransferFunction[I])},transform:function(i){var f=p(parseInt(i[0])),h=parseFloat(i[1]),C=parseFloat(i[2]),A=parseFloat(i[3]),L=parseFloat(i[4]),I=parseFloat(i[5]),E=parseFloat(i[6]);u.transform(f,h,C,A,L,I,E)},undefine:function(f){var h=parseInt(f[0]),C=P[h];C&&C.onundefine&&C.onundefine()},video:function(i){var f=parseInt(i[0]),h=p(parseInt(i[1])),C=i[2],A=_[f]=new n.InputStream(e,f),L=null;e.onvideo&&(L=e.onvideo(A,h,C)),L||(L=n.VideoPlayer.getInstance(A,h,C)),L?(T[f]=L,e.sendAck(f,"OK",0)):e.sendAck(f,"BAD TYPE",783)}},O=function(){r.sendMessage("nop"),d=new Date().getTime()},F=function(){window.clearTimeout(o);var f=new Date().getTime(),h=Math.max(d+s-f,0);h>0?o=window.setTimeout(O,h):O()},H=function(){window.clearTimeout(o)};r.oninstruction=function(i,f){var h=M[i];h&&h(f),F()},this.disconnect=function(){t!=n.Client.State.DISCONNECTED&&t!=n.Client.State.DISCONNECTING&&(v(n.Client.State.DISCONNECTING),H(),r.sendMessage("disconnect"),r.disconnect(),v(n.Client.State.DISCONNECTED))},this.connect=function(i){v(n.Client.State.CONNECTING);try{r.connect(i)}catch(f){throw v(n.Client.State.IDLE),f}F(),v(n.Client.State.WAITING)}};n.Client.State={IDLE:0,CONNECTING:1,WAITING:2,CONNECTED:3,DISCONNECTING:4,DISCONNECTED:5};n.Client.DefaultTransferFunction={0:function(r,e){e.red=e.green=e.blue=0},15:function(r,e){e.red=e.green=e.blue=255},3:function(r,e){e.red=r.red,e.green=r.green,e.blue=r.blue,e.alpha=r.alpha},5:function(r,e){},12:function(r,e){e.red=255&~r.red,e.green=255&~r.green,e.blue=255&~r.blue,e.alpha=r.alpha},10:function(r,e){e.red=255&~e.red,e.green=255&~e.green,e.blue=255&~e.blue},1:function(r,e){e.red=r.red&e.red,e.green=r.green&e.green,e.blue=r.blue&e.blue},14:function(r,e){e.red=255&~(r.red&e.red),e.green=255&~(r.green&e.green),e.blue=255&~(r.blue&e.blue)},7:function(r,e){e.red=r.red|e.red,e.green=r.green|e.green,e.blue=r.blue|e.blue},8:function(r,e){e.red=255&~(r.red|e.red),e.green=255&~(r.green|e.green),e.blue=255&~(r.blue|e.blue)},6:function(r,e){e.red=r.red^e.red,e.green=r.green^e.green,e.blue=r.blue^e.blue},9:function(r,e){e.red=255&~(r.red^e.red),e.green=255&~(r.green^e.green),e.blue=255&~(r.blue^e.blue)},4:function(r,e){e.red=255&(~r.red&e.red),e.green=255&(~r.green&e.green),e.blue=255&(~r.blue&e.blue)},13:function(r,e){e.red=255&(~r.red|e.red),e.green=255&(~r.green|e.green),e.blue=255&(~r.blue|e.blue)},2:function(r,e){e.red=255&(r.red&~e.red),e.green=255&(r.green&~e.green),e.blue=255&(r.blue&~e.blue)},11:function(r,e){e.red=255&(r.red|~e.red),e.green=255&(r.green|~e.green),e.blue=255&(r.blue|~e.blue)}};n.Client.Message={USER_JOINED:1,USER_LEFT:2};var n=n||{};n.DataURIReader=function(r,e){var t=this,a="data:"+e+";base64,";r.onblob=function(o){a+=o},r.onend=function(){t.onend&&t.onend()},this.getURI=function(){return a},this.onend=null};var n=n||{};n.Display=function(){var r=this,e=0,t=0,a=1,s=document.createElement("div");s.style.position="relative",s.style.width=e+"px",s.style.height=t+"px",s.style.transformOrigin=s.style.webkitTransformOrigin=s.style.MozTransformOrigin=s.style.OTransformOrigin=s.style.msTransformOrigin="0 0";var o=new n.Display.VisibleLayer(e,t),d=new n.Display.VisibleLayer(0,0);d.setChannelMask(n.Layer.SRC),s.appendChild(o.getElement()),s.appendChild(d.getElement());var c=document.createElement("div");c.style.position="relative",c.style.width=e*a+"px",c.style.height=t*a+"px",c.appendChild(s),this.cursorHotspotX=0,this.cursorHotspotY=0,this.cursorX=0,this.cursorY=0,this.statisticWindow=0,this.onresize=null,this.oncursor=null,this.onstatistics=null;var x=[],u=[],y=function(){for(var v=0,g=0,p=0,m=0;m<u.length;){var S=u[m];if(!S.isReady())break;S.flush(),v=S.localTimestamp,g=S.remoteTimestamp,p+=S.logicalFrames,m++}u.splice(0,m),m&&T(v,g,p)},w=[],T=function(v,g,p){if(r.statisticWindow){for(var m=new Date().getTime(),S=0;S<w.length&&!(m-w[S].timestamp<=r.statisticWindow);S++);w.splice(0,S-1),w.push({localTimestamp:v,remoteTimestamp:g,timestamp:m,frames:p});var R=(w[w.length-1].timestamp-w[0].timestamp)/1e3,M=(w[w.length-1].remoteTimestamp-w[0].remoteTimestamp)/1e3,O=w.length,F=w.reduce(function(h,C){return h+C.frames},0),H=w.reduce(function(h,C){return h+Math.max(0,C.frames-1)},0),i=new n.Display.Statistics({processingLag:m-v,desktopFps:M&&F?F/M:null,clientFps:R?O/R:null,serverFps:M?O/M:null,dropRate:M?H/M:null});r.onstatistics&&r.onstatistics(i)}};function k(){y()}var _=function(v,g,p,m){this.localTimestamp=new Date().getTime(),this.remoteTimestamp=p||this.localTimestamp,this.logicalFrames=m||0,this.cancel=function(){v=null,g.forEach(function(M){M.cancel()}),g=[]},this.isReady=function(){for(var S=0;S<g.length;S++)if(g[S].blocked)return!1;return!0},this.flush=function(){for(var S=0;S<g.length;S++)g[S].execute();v&&v()}};function P(l,v){var g=this;this.blocked=v,this.cancel=function(){g.blocked=!1,l=null},this.unblock=function(){g.blocked&&(g.blocked=!1,u.length&&k())},this.execute=function(){l&&l()}}function b(l,v){var g=new P(l,v);return x.push(g),g}this.getElement=function(){return c},this.getWidth=function(){return e},this.getHeight=function(){return t},this.getDefaultLayer=function(){return o},this.getCursorLayer=function(){return d},this.createLayer=function(){var l=new n.Display.VisibleLayer(e,t);return l.move(o,0,0,0),l},this.createBuffer=function(){var l=new n.Layer(0,0);return l.autosize=1,l},this.flush=function(l,v,g){u.push(new _(l,x,v,g)),x=[],k()},this.cancel=function(){u.forEach(function(g){g.cancel()}),u=[],x.forEach(function(g){g.cancel()}),x=[]},this.setCursor=function(l,v,g,p,m,S,R){b(function(){r.cursorHotspotX=l,r.cursorHotspotY=v,d.resize(S,R),d.copy(g,p,m,S,R,0,0),r.moveCursor(r.cursorX,r.cursorY),r.oncursor&&r.oncursor(d.toCanvas(),l,v)})},this.showCursor=function(l){var v=d.getElement(),g=v.parentNode;l===!1?g&&g.removeChild(v):g!==s&&s.appendChild(v)},this.moveCursor=function(l,v){d.translate(l-r.cursorHotspotX,v-r.cursorHotspotY),r.cursorX=l,r.cursorY=v},this.resize=function(l,v,g){b(function(){l.resize(v,g),l===o&&(e=v,t=g,s.style.width=e+"px",s.style.height=t+"px",c.style.width=e*a+"px",c.style.height=t*a+"px",r.onresize&&r.onresize(v,g))})},this.drawImage=function(l,v,g,p){b(function(){l.drawImage(v,g,p)})},this.drawBlob=function(l,v,g,p){var m;if(window.createImageBitmap){var S;m=b(function(){l.drawImage(v,g,S)},!0),window.createImageBitmap(p).then(function(F){S=F,m.unblock()})}else{var R=URL.createObjectURL(p);m=b(function(){M.width&&M.height&&l.drawImage(v,g,M),URL.revokeObjectURL(R)},!0);var M=new Image;M.onload=m.unblock,M.onerror=m.unblock,M.src=R}},this.drawStream=function(v,g,p,m,S){if(window.ImageDecoder&&window.ReadableStream){var R=new ImageDecoder({type:S,data:m.toReadableStream()}),M=null,O=b(function(){v.drawImage(g,p,M)},!0);R.decode({completeFramesOnly:!0}).then(function(i){M=i.image,O.unblock()})}else{var F=new n.DataURIReader(m,S);F.onend=function(){r.draw(v,g,p,F.getURI())}}},this.draw=function(l,v,g,p){var m=b(function(){S.width&&S.height&&l.drawImage(v,g,S)},!0),S=new Image;S.onload=m.unblock,S.onerror=m.unblock,S.src=p},this.play=function(l,v,g,p){var m=document.createElement("video");m.type=v,m.src=p,m.addEventListener("play",function(){function S(){l.drawImage(0,0,m),m.ended||window.setTimeout(S,20)}S()},!1),b(m.play)},this.transfer=function(l,v,g,p,m,S,R,M,O){b(function(){S.transfer(l,v,g,p,m,R,M,O)})},this.put=function(l,v,g,p,m,S,R,M){b(function(){S.put(l,v,g,p,m,R,M)})},this.copy=function(l,v,g,p,m,S,R,M){b(function(){S.copy(l,v,g,p,m,R,M)})},this.moveTo=function(l,v,g){b(function(){l.moveTo(v,g)})},this.lineTo=function(l,v,g){b(function(){l.lineTo(v,g)})},this.arc=function(l,v,g,p,m,S,R){b(function(){l.arc(v,g,p,m,S,R)})},this.curveTo=function(l,v,g,p,m,S,R){b(function(){l.curveTo(v,g,p,m,S,R)})},this.close=function(l){b(function(){l.close()})},this.rect=function(l,v,g,p,m){b(function(){l.rect(v,g,p,m)})},this.clip=function(l){b(function(){l.clip()})},this.strokeColor=function(l,v,g,p,m,S,R,M){b(function(){l.strokeColor(v,g,p,m,S,R,M)})},this.fillColor=function(l,v,g,p,m){b(function(){l.fillColor(v,g,p,m)})},this.strokeLayer=function(l,v,g,p,m){b(function(){l.strokeLayer(v,g,p,m)})},this.fillLayer=function(l,v){b(function(){l.fillLayer(v)})},this.push=function(l){b(function(){l.push()})},this.pop=function(l){b(function(){l.pop()})},this.reset=function(l){b(function(){l.reset()})},this.setTransform=function(l,v,g,p,m,S,R){b(function(){l.setTransform(v,g,p,m,S,R)})},this.transform=function(l,v,g,p,m,S,R){b(function(){l.transform(v,g,p,m,S,R)})},this.setChannelMask=function(l,v){b(function(){l.setChannelMask(v)})},this.setMiterLimit=function(l,v){b(function(){l.setMiterLimit(v)})},this.dispose=function(v){b(function(){v.dispose()})},this.distort=function(v,g,p,m,S,R,M){b(function(){v.distort(g,p,m,S,R,M)})},this.move=function(v,g,p,m,S){b(function(){v.move(g,p,m,S)})},this.shade=function(v,g){b(function(){v.shade(g)})},this.scale=function(l){s.style.transform=s.style.WebkitTransform=s.style.MozTransform=s.style.OTransform=s.style.msTransform="scale("+l+","+l+")",a=l,c.style.width=e*a+"px",c.style.height=t*a+"px"},this.getScale=function(){return a},this.flatten=function(){var l=document.createElement("canvas");l.width=o.width,l.height=o.height;var v=l.getContext("2d");function g(m){var S=[];for(var R in m.children)S.push(m.children[R]);return S.sort(function(O,F){var H=O.z-F.z;if(H!==0)return H;var i=O.getElement(),f=F.getElement(),h=f.compareDocumentPosition(i);return h&Node.DOCUMENT_POSITION_PRECEDING?-1:h&Node.DOCUMENT_POSITION_FOLLOWING?1:0}),S}function p(m,S,R){if(m.width>0&&m.height>0){var M=v.globalAlpha;v.globalAlpha*=m.alpha/255,v.drawImage(m.getCanvas(),S,R);for(var O=g(m),F=0;F<O.length;F++){var H=O[F];p(H,S+H.x,R+H.y)}v.globalAlpha=M}}return p(o,0,0),l}};n.Display.VisibleLayer=function(r,e){n.Layer.apply(this,[r,e]);var t=this;this.__unique_id=n.Display.VisibleLayer.__next_id++,this.alpha=255,this.x=0,this.y=0,this.z=0,this.matrix=[1,0,0,1,0,0],this.parent=null,this.children={};var a=t.getCanvas();a.style.position="absolute",a.style.left="0px",a.style.top="0px";var s=document.createElement("div");s.appendChild(a),s.style.width=r+"px",s.style.height=e+"px",s.style.position="absolute",s.style.left="0px",s.style.top="0px",s.style.overflow="hidden";var o=this.resize;this.resize=function(x,u){s.style.width=x+"px",s.style.height=u+"px",o(x,u)},this.getElement=function(){return s};var d="translate(0px, 0px)",c="matrix(1, 0, 0, 1, 0, 0)";this.translate=function(x,u){t.x=x,t.y=u,d="translate("+x+"px,"+u+"px)",s.style.transform=s.style.WebkitTransform=s.style.MozTransform=s.style.OTransform=s.style.msTransform=d+" "+c},this.move=function(x,u,y,w){if(t.parent!==x){t.parent&&delete t.parent.children[t.__unique_id],t.parent=x,x.children[t.__unique_id]=t;var T=x.getElement();T.appendChild(s)}t.translate(u,y),t.z=w,s.style.zIndex=w},this.shade=function(x){t.alpha=x,s.style.opacity=x/255},this.dispose=function(){t.parent&&(delete t.parent.children[t.__unique_id],t.parent=null),s.parentNode&&s.parentNode.removeChild(s)},this.distort=function(x,u,y,w,T,k){t.matrix=[x,u,y,w,T,k],c="matrix("+x+","+u+","+y+","+w+","+T+","+k+")",s.style.transform=s.style.WebkitTransform=s.style.MozTransform=s.style.OTransform=s.style.msTransform=d+" "+c}};n.Display.VisibleLayer.__next_id=0;n.Display.Statistics=function(e){e=e||{},this.processingLag=e.processingLag,this.desktopFps=e.desktopFps,this.serverFps=e.serverFps,this.clientFps=e.clientFps,this.dropRate=e.dropRate};var n=n||{};n.Event=function(e){this.type=e,this.timestamp=new Date().getTime(),this.getAge=function(){return new Date().getTime()-this.timestamp},this.invokeLegacyHandler=function(a){}};n.Event.DOMEvent=function(e,t){n.Event.call(this,e),t=t||[],Array.isArray(t)||(t=[t]),this.preventDefault=function(){t.forEach(function(o){o.preventDefault&&o.preventDefault(),o.returnValue=!1})},this.stopPropagation=function(){t.forEach(function(o){o.stopPropagation()})}};n.Event.DOMEvent.cancelEvent=function(e){e.stopPropagation(),e.preventDefault&&e.preventDefault(),e.returnValue=!1};n.Event.Target=function(){var e={};this.on=function(a,s){var o=e[a];o||(e[a]=o=[]),o.push(s)},this.onEach=function(a,s){a.forEach(function(d){this.on(d,s)},this)},this.dispatch=function(a){a.invokeLegacyHandler(this);var s=e[a.type];if(s)for(var o=0;o<s.length;o++)s[o](a,this)},this.off=function(a,s){var o=e[a];if(!o)return!1;for(var d=0;d<o.length;d++)if(o[d]===s)return o.splice(d,1),!0;return!1},this.offEach=function(a,s){var o=!1;return a.forEach(function(c){o|=this.off(c,s)},this),o}};var n=n||{};n.InputSink=function(){var e=this,t=document.createElement("textarea");t.style.position="fixed",t.style.outline="none",t.style.border="none",t.style.margin="0",t.style.padding="0",t.style.height="0",t.style.width="0",t.style.left="0",t.style.bottom="0",t.style.resize="none",t.style.background="transparent",t.style.color="transparent",t.addEventListener("keypress",function(s){t.value=""},!1),t.addEventListener("compositionend",function(s){s.data&&(t.value="")},!1),t.addEventListener("input",function(s){s.data&&!s.isComposing&&(t.value="")},!1),t.addEventListener("focus",function(){window.setTimeout(function(){t.click(),t.select()},0)},!0),this.focus=function(){window.setTimeout(function(){t.focus()},0)},this.getElement=function(){return t},document.addEventListener("keydown",function(s){var o=document.activeElement;if(o&&o!==document.body){var d=o.getBoundingClientRect();if(d.left+d.width>0&&d.top+d.height>0)return}e.focus()},!0)};var n=n||{};n.InputStream=function(r,e){var t=this;this.index=e,this.onblob=null,this.onend=null,this.sendAck=function(a,s){r.sendAck(t.index,a,s)},this.toReadableStream=function(){return new ReadableStream({type:"bytes",start:function(o){var d=new n.ArrayBufferReader(t);d.ondata=function(x){if(o.byobRequest){var u=o.byobRequest.view,y=Math.min(u.byteLength,x.byteLength),w=new Uint8Array(x,0,y);u.buffer.set(w),o.byobRequest.respond(y),y<x.byteLength&&o.enqueue(x.slice(y))}else o.enqueue(new Uint8Array(x))},d.onend=function(){o.close()}}})}};var n=n||{};n.IntegerPool=function(){var r=this,e=[];this.next_int=0,this.next=function(){return e.length>0?e.shift():r.next_int++},this.free=function(t){e.push(t)}};var n=n||{};n.JSONReader=function(e){var t=this,a=new n.StringReader(e),s="";this.getLength=function(){return s.length},this.getJSON=function(){return JSON.parse(s)},a.ontext=function(d){s+=d,t.onprogress&&t.onprogress(d.length)},a.onend=function(){t.onend&&t.onend()},this.onprogress=null,this.onend=null};var n=n||{};n.Keyboard=function(e){var t=this,a=n.Keyboard._nextID++,s="_GUAC_KEYBOARD_HANDLED_BY_"+a;this.onkeydown=null,this.onkeyup=null;var o={keyupUnreliable:!1,altIsTypableOnly:!1,capsLockKeyEventUnreliable:!1};navigator&&navigator.platform&&(navigator.platform.match(/ipad|iphone|ipod/i)?o.keyupUnreliable=!0:navigator.platform.match(/^mac/i)&&(o.altIsTypableOnly=!0,o.capsLockKeyEventUnreliable=!0));var d=function(E){var D=this;this.keyCode=E?E.which||E.keyCode:0,this.keyIdentifier=E&&E.keyIdentifier,this.key=E&&E.key,this.location=E?A(E):0,this.modifiers=E?n.Keyboard.ModifierState.fromKeyboardEvent(E):new n.Keyboard.ModifierState,this.timestamp=new Date().getTime(),this.defaultPrevented=!1,this.keysym=null,this.reliable=!1,this.getAge=function(){return new Date().getTime()-D.timestamp}},c=function(E){d.call(this,E),this.keysym=m(this.key,this.location)||M(this.keyCode,this.location),this.keyupReliable=!o.keyupUnreliable,this.keysym&&!p(this.keysym)&&(this.reliable=!0),!this.keysym&&O(this.keyCode,this.keyIdentifier)&&(this.keysym=m(this.keyIdentifier,this.location,this.modifiers.shift)),this.modifiers.meta&&this.keysym!==65511&&this.keysym!==65512?this.keyupReliable=!1:this.keysym===65509&&o.capsLockKeyEventUnreliable&&(this.keyupReliable=!1);var D=!this.modifiers.ctrl&&!o.altIsTypableOnly;o.altIsTypableOnly&&(this.keysym===65513||this.keysym===65514)&&(this.keysym=65027);var B=!this.modifiers.alt;(B&&this.modifiers.ctrl||D&&this.modifiers.alt||this.modifiers.meta||this.modifiers.hyper)&&(this.reliable=!0),b[this.keyCode]=this.keysym};c.prototype=new d;var x=function(E){d.call(this,E),this.keysym=R(this.keyCode),this.reliable=!0};x.prototype=new d;var u=function(E){if(d.call(this,E),this.keyCode==20&&o.capsLockKeyEventUnreliable){y.push(new c(this));return}this.keysym=M(this.keyCode,this.location)||m(this.key,this.location),t.pressed[this.keysym]||(this.keysym=b[this.keyCode]||this.keysym),this.reliable=!0};u.prototype=new d;var y=[],w={8:[65288],9:[65289],12:[65291,65291,65291,65461],13:[65293],16:[65505,65505,65506],17:[65507,65507,65508],18:[65513,65513,65514],19:[65299],20:[65509],27:[65307],32:[32],33:[65365,65365,65365,65465],34:[65366,65366,65366,65459],35:[65367,65367,65367,65457],36:[65360,65360,65360,65463],37:[65361,65361,65361,65460],38:[65362,65362,65362,65464],39:[65363,65363,65363,65462],40:[65364,65364,65364,65458],45:[65379,65379,65379,65456],46:[65535,65535,65535,65454],91:[65511],92:[65512],93:[65383],96:[65456],97:[65457],98:[65458],99:[65459],100:[65460],101:[65461],102:[65462],103:[65463],104:[65464],105:[65465],106:[65450],107:[65451],109:[65453],110:[65454],111:[65455],112:[65470],113:[65471],114:[65472],115:[65473],116:[65474],117:[65475],118:[65476],119:[65477],120:[65478],121:[65479],122:[65480],123:[65481],144:[65407],145:[65300],225:[65027]},T={Again:[65382],AllCandidates:[65341],Alphanumeric:[65328],Alt:[65513,65513,65514],Attn:[64782],AltGraph:[65027],ArrowDown:[65364],ArrowLeft:[65361],ArrowRight:[65363],ArrowUp:[65362],Backspace:[65288],CapsLock:[65509],Cancel:[65385],Clear:[65291],Convert:[65315],Copy:[64789],Crsel:[64796],CrSel:[64796],CodeInput:[65335],Compose:[65312],Control:[65507,65507,65508],ContextMenu:[65383],Delete:[65535],Down:[65364],End:[65367],Enter:[65293],EraseEof:[64774],Escape:[65307],Execute:[65378],Exsel:[64797],ExSel:[64797],F1:[65470],F2:[65471],F3:[65472],F4:[65473],F5:[65474],F6:[65475],F7:[65476],F8:[65477],F9:[65478],F10:[65479],F11:[65480],F12:[65481],F13:[65482],F14:[65483],F15:[65484],F16:[65485],F17:[65486],F18:[65487],F19:[65488],F20:[65489],F21:[65490],F22:[65491],F23:[65492],F24:[65493],Find:[65384],GroupFirst:[65036],GroupLast:[65038],GroupNext:[65032],GroupPrevious:[65034],FullWidth:null,HalfWidth:null,HangulMode:[65329],Hankaku:[65321],HanjaMode:[65332],Help:[65386],Hiragana:[65317],HiraganaKatakana:[65319],Home:[65360],Hyper:[65517,65517,65518],Insert:[65379],JapaneseHiragana:[65317],JapaneseKatakana:[65318],JapaneseRomaji:[65316],JunjaMode:[65336],KanaMode:[65325],KanjiMode:[65313],Katakana:[65318],Left:[65361],Meta:[65511,65511,65512],ModeChange:[65406],NonConvert:[65314],NumLock:[65407],PageDown:[65366],PageUp:[65365],Pause:[65299],Play:[64790],PreviousCandidate:[65342],PrintScreen:[65377],Redo:[65382],Right:[65363],Romaji:[65316],RomanCharacters:null,Scroll:[65300],Select:[65376],Separator:[65452],Shift:[65505,65505,65506],SingleCandidate:[65340],Super:[65515,65515,65516],Tab:[65289],UIKeyInputDownArrow:[65364],UIKeyInputEscape:[65307],UIKeyInputLeftArrow:[65361],UIKeyInputRightArrow:[65363],UIKeyInputUpArrow:[65362],Up:[65362],Undo:[65381],Win:[65511,65511,65512],Zenkaku:[65320],ZenkakuHankaku:[65322]},k={65027:!0,65505:!0,65506:!0,65507:!0,65508:!0,65509:!0,65511:!0,65512:!0,65513:!0,65514:!0,65515:!0,65516:!0};this.modifiers=new n.Keyboard.ModifierState,this.pressed={};var _={},P={},b={},l=null,v=null,g=function(E,D){return E?E[D]||E[0]:null},p=function(E){return E>=0&&E<=255||(E&4294901760)===16777216};function m(I,E,D){if(!I)return null;var B,Y=I.indexOf("U+");if(Y>=0){var U=I.substring(Y+2);B=String.fromCharCode(parseInt(U,16))}else if(I.length===1&&E!==3)B=I;else return g(T[I],E);D===!0?B=B.toUpperCase():D===!1&&(B=B.toLowerCase());var N=B.charCodeAt(0);return R(N)}function S(I){return I<=31||I>=127&&I<=159}function R(I){return S(I)?65280|I:I>=0&&I<=255?I:I>=256&&I<=1114111?16777216|I:null}function M(I,E){return g(w[I],E)}var O=function(E,D){if(!D)return!1;var B=D.indexOf("U+");if(B===-1)return!0;var Y=parseInt(D.substring(B+2),16);return E!==Y||E>=65&&E<=90||E>=48&&E<=57};this.press=function(I){if(I!==null){if(!t.pressed[I]&&(t.pressed[I]=!0,t.onkeydown)){var E=t.onkeydown(I);return P[I]=E,window.clearTimeout(l),window.clearInterval(v),k[I]||(l=window.setTimeout(function(){v=window.setInterval(function(){t.onkeyup(I),t.onkeydown(I)},50)},500)),E}return P[I]||!1}},this.release=function(I){t.pressed[I]&&(delete t.pressed[I],delete _[I],window.clearTimeout(l),window.clearInterval(v),I!==null&&t.onkeyup&&t.onkeyup(I))},this.type=function(E){for(var D=0;D<E.length;D++){var B=E.codePointAt?E.codePointAt(D):E.charCodeAt(D),Y=R(B);t.press(Y),t.release(Y)}},this.reset=function(){for(var I in t.pressed)t.release(parseInt(I));y=[]};var F=function(E,D,B){var Y=B.modifiers[E],U=t.modifiers[E],N;if(D.indexOf(B.keysym)===-1){if(U&&Y===!1)for(N=0;N<D.length;N++)t.release(D[N]);else if(!U&&Y){for(N=0;N<D.length;N++)if(t.pressed[D[N]])return;var W=D[0];B.keysym&&(_[W]=!0),t.press(W)}}},H=function(E){F("alt",[65513,65514,65027],E),F("shift",[65505,65506],E),F("ctrl",[65507,65508],E),F("meta",[65511,65512],E),F("hyper",[65515,65516],E),t.modifiers=E.modifiers},i=function(){for(var E in t.pressed)if(!_[E])return!1;return!0};function f(){var I=C();if(!I)return!1;var E;do E=I,I=C();while(I!==null);return i()&&t.reset(),E.defaultPrevented}var h=function(E){!t.modifiers.ctrl||!t.modifiers.alt||E>=65&&E<=90||E>=97&&E<=122||(E<=255||(E&4278190080)===16777216)&&(t.release(65507),t.release(65508),t.release(65513),t.release(65514))},C=function(){var E=y[0];if(!E)return null;if(E instanceof c){var D=null,B=[];if(E.keysym===65511||E.keysym===65512){if(y.length===1)return null;if(y[1].keysym!==E.keysym){if(!y[1].modifiers.meta)return y.shift()}else if(y[1]instanceof c)return y.shift()}if(E.reliable?(D=E.keysym,B=y.splice(0,1)):y[1]instanceof x?(D=y[1].keysym,B=y.splice(0,2)):y[1]&&(D=E.keysym,B=y.splice(0,1)),B.length>0){if(H(E),D){h(D);var Y=!t.press(D);b[E.keyCode]=D,E.keyupReliable||t.release(D);for(var U=0;U<B.length;U++)B[U].defaultPrevented=Y}return E}}else if(E instanceof u&&!o.keyupUnreliable){var D=E.keysym;if(D)t.release(D),delete b[E.keyCode],E.defaultPrevented=!0;else return t.reset(),E;return H(E),y.shift()}else return y.shift();return null},A=function(E){return"location"in E?E.location:"keyLocation"in E?E.keyLocation:0},L=function(E){return E[s]?!1:(E[s]=!0,!0)};this.listenTo=function(E){E.addEventListener("keydown",function(U){if(t.onkeydown&&L(U)){var N=new c(U);U.isComposing||N.keyCode===229||(y.push(N),f()&&U.preventDefault())}},!0),E.addEventListener("keypress",function(U){!t.onkeydown&&!t.onkeyup||L(U)&&(y.push(new x(U)),f()&&U.preventDefault())},!0),E.addEventListener("keyup",function(U){t.onkeyup&&L(U)&&(U.preventDefault(),y.push(new u(U)),f())},!0);var D=function(N){!t.onkeydown&&!t.onkeyup||L(N)&&N.data&&!N.isComposing&&t.type(N.data)},B=function(N){E.removeEventListener("input",D,!1)},Y=function(N){!t.onkeydown&&!t.onkeyup||L(N)&&N.data&&t.type(N.data)};E.addEventListener("input",D,!1),E.addEventListener("compositionend",Y,!1),E.addEventListener("compositionstart",B,!1)},e&&t.listenTo(e)};n.Keyboard._nextID=0;n.Keyboard.ModifierState=function(){this.shift=!1,this.ctrl=!1,this.alt=!1,this.meta=!1,this.hyper=!1};n.Keyboard.ModifierState.fromKeyboardEvent=function(r){var e=new n.Keyboard.ModifierState;return e.shift=r.shiftKey,e.ctrl=r.ctrlKey,e.alt=r.altKey,e.meta=r.metaKey,r.getModifierState&&(e.hyper=r.getModifierState("OS")||r.getModifierState("Super")||r.getModifierState("Hyper")||r.getModifierState("Win")),e};var n=n||{};n.KeyEventInterpreter=function(e){e==null&&(e=0);var t=[{keysym:65027,name:"AltGr"},{keysym:65288,name:"Backspace"},{keysym:65289,name:"Tab"},{keysym:65291,name:"Clear"},{keysym:65293,name:"Return",value:`\n`},{keysym:65299,name:"Pause"},{keysym:65300,name:"Scroll"},{keysym:65301,name:"SysReq"},{keysym:65307,name:"Escape"},{keysym:65360,name:"Home"},{keysym:65361,name:"Left"},{keysym:65362,name:"Up"},{keysym:65363,name:"Right"},{keysym:65364,name:"Down"},{keysym:65365,name:"Page Up"},{keysym:65366,name:"Page Down"},{keysym:65367,name:"End"},{keysym:65379,name:"Insert"},{keysym:65381,name:"Undo"},{keysym:65386,name:"Help"},{keysym:65407,name:"Num"},{keysym:65408,name:"Space",value:" "},{keysym:65421,name:"Enter",value:`\n`},{keysym:65429,name:"Home"},{keysym:65430,name:"Left"},{keysym:65431,name:"Up"},{keysym:65432,name:"Right"},{keysym:65433,name:"Down"},{keysym:65434,name:"Page Up"},{keysym:65435,name:"Page Down"},{keysym:65436,name:"End"},{keysym:65438,name:"Insert"},{keysym:65450,name:"*",value:"*"},{keysym:65451,name:"+",value:"+"},{keysym:65453,name:"-",value:"-"},{keysym:65454,name:".",value:"."},{keysym:65455,name:"/",value:"/"},{keysym:65456,name:"0",value:"0"},{keysym:65457,name:"1",value:"1"},{keysym:65458,name:"2",value:"2"},{keysym:65459,name:"3",value:"3"},{keysym:65460,name:"4",value:"4"},{keysym:65461,name:"5",value:"5"},{keysym:65462,name:"6",value:"6"},{keysym:65463,name:"7",value:"7"},{keysym:65464,name:"8",value:"8"},{keysym:65465,name:"9",value:"9"},{keysym:65470,name:"F1"},{keysym:65471,name:"F2"},{keysym:65472,name:"F3"},{keysym:65473,name:"F4"},{keysym:65474,name:"F5"},{keysym:65475,name:"F6"},{keysym:65476,name:"F7"},{keysym:65477,name:"F8"},{keysym:65478,name:"F9"},{keysym:65479,name:"F10"},{keysym:65480,name:"F11"},{keysym:65481,name:"F12"},{keysym:65482,name:"F13"},{keysym:65483,name:"F14"},{keysym:65484,name:"F15"},{keysym:65485,name:"F16"},{keysym:65486,name:"F17"},{keysym:65487,name:"F18"},{keysym:65488,name:"F19"},{keysym:65489,name:"F20"},{keysym:65490,name:"F21"},{keysym:65491,name:"F22"},{keysym:65492,name:"F23"},{keysym:65493,name:"F24"},{keysym:65505,name:"Shift"},{keysym:65506,name:"Shift"},{keysym:65507,name:"Ctrl"},{keysym:65508,name:"Ctrl"},{keysym:65509,name:"Caps"},{keysym:65511,name:"Meta"},{keysym:65512,name:"Meta"},{keysym:65513,name:"Alt"},{keysym:65514,name:"Alt"},{keysym:65515,name:"Super"},{keysym:65516,name:"Super"},{keysym:65517,name:"Hyper"},{keysym:65518,name:"Hyper"},{keysym:65535,name:"Delete"}],a={};t.forEach(function(x){a[x.keysym]=new n.KeyEventInterpreter.KeyDefinition(x)});var s=[];function o(c){if(c<0||c>255&&(c|65535)!=16842751)return null;var x=c&65535,u=String.fromCharCode(x);return new n.KeyEventInterpreter.KeyDefinition({keysym:c,name:u,value:u})}function d(c){if(c in a)return a[c];var x=o(c);return x??new n.KeyEventInterpreter.KeyDefinition({keysym:c,name:"0x"+String(c.toString(16))})}this.handleKeyEvent=function(x){var u=parseInt(x[0]),y=parseInt(x[1]),w=parseInt(x[2]),T=w-e,k=d(u);s.push(new n.KeyEventInterpreter.KeyEvent({definition:k,pressed:y,timestamp:T}))},this.getEvents=function(){return s}};n.KeyEventInterpreter.KeyDefinition=function(e){e=e||{},this.keysym=parseInt(e.keysym),this.name=e.name,this.value=e.value};n.KeyEventInterpreter.KeyEvent=function(e){e=e||{},this.definition=e.definition,this.pressed=!!e.pressed,this.timestamp=e.timestamp};var n=n||{};n.Layer=function(r,e){var t=this,a=64,s=document.createElement("canvas"),o=s.getContext("2d");o.save();var d=!0,c=!0,x=0,u={1:"destination-in",2:"destination-out",4:"source-in",6:"source-atop",8:"source-out",9:"destination-atop",10:"xor",11:"destination-over",12:"copy",14:"source-over",15:"lighter"},y=function(k,_){k=k||0,_=_||0;var P=Math.ceil(k/a)*a,b=Math.ceil(_/a)*a;if(s.width!==P||s.height!==b){var l=null;if(!d&&s.width!==0&&s.height!==0){l=document.createElement("canvas"),l.width=Math.min(t.width,k),l.height=Math.min(t.height,_);var v=l.getContext("2d");v.drawImage(s,0,0,l.width,l.height,0,0,l.width,l.height)}var g=o.globalCompositeOperation;s.width=P,s.height=b,l&&o.drawImage(l,0,0,l.width,l.height,0,0,l.width,l.height),o.globalCompositeOperation=g,x=0,o.save()}else t.reset();t.width=k,t.height=_};function w(T,k,_,P){var b=_+T,l=P+k,v;b>t.width?v=b:v=t.width;var g;l>t.height?g=l:g=t.height,t.resize(v,g)}this.autosize=!1,this.width=r,this.height=e,this.getCanvas=function(){return s},this.toCanvas=function(){var k=document.createElement("canvas");k.width=t.width,k.height=t.height;var _=k.getContext("2d");return _.drawImage(t.getCanvas(),0,0),k},this.resize=function(T,k){(T!==t.width||k!==t.height)&&y(T,k)},this.drawImage=function(T,k,_){t.autosize&&w(T,k,_.width,_.height),o.drawImage(_,T,k),d=!1},this.transfer=function(T,k,_,P,b,l,v,g){var p=T.getCanvas();if(!(k>=p.width||_>=p.height)&&(k+P>p.width&&(P=p.width-k),_+b>p.height&&(b=p.height-_),!(P===0||b===0))){t.autosize&&w(l,v,P,b);for(var m=T.getCanvas().getContext("2d").getImageData(k,_,P,b),S=o.getImageData(l,v,P,b),R=0;R<P*b*4;R+=4){var M=new n.Layer.Pixel(m.data[R],m.data[R+1],m.data[R+2],m.data[R+3]),O=new n.Layer.Pixel(S.data[R],S.data[R+1],S.data[R+2],S.data[R+3]);g(M,O),S.data[R]=O.red,S.data[R+1]=O.green,S.data[R+2]=O.blue,S.data[R+3]=O.alpha}o.putImageData(S,l,v),d=!1}},this.put=function(T,k,_,P,b,l,v){var g=T.getCanvas();if(!(k>=g.width||_>=g.height)&&(k+P>g.width&&(P=g.width-k),_+b>g.height&&(b=g.height-_),!(P===0||b===0))){t.autosize&&w(l,v,P,b);var p=T.getCanvas().getContext("2d").getImageData(k,_,P,b);o.putImageData(p,l,v),d=!1}},this.copy=function(T,k,_,P,b,l,v){var g=T.getCanvas();k>=g.width||_>=g.height||(k+P>g.width&&(P=g.width-k),_+b>g.height&&(b=g.height-_),!(P===0||b===0)&&(t.autosize&&w(l,v,P,b),o.drawImage(g,k,_,P,b,l,v,P,b),d=!1))},this.moveTo=function(T,k){c&&(o.beginPath(),c=!1),t.autosize&&w(T,k,0,0),o.moveTo(T,k)},this.lineTo=function(T,k){c&&(o.beginPath(),c=!1),t.autosize&&w(T,k,0,0),o.lineTo(T,k)},this.arc=function(T,k,_,P,b,l){c&&(o.beginPath(),c=!1),t.autosize&&w(T,k,0,0),o.arc(T,k,_,P,b,l)},this.curveTo=function(T,k,_,P,b,l){c&&(o.beginPath(),c=!1),t.autosize&&w(b,l,0,0),o.bezierCurveTo(T,k,_,P,b,l)},this.close=function(){o.closePath(),c=!0},this.rect=function(T,k,_,P){c&&(o.beginPath(),c=!1),t.autosize&&w(T,k,_,P),o.rect(T,k,_,P)},this.clip=function(){o.clip(),c=!0},this.strokeColor=function(T,k,_,P,b,l,v){o.lineCap=T,o.lineJoin=k,o.lineWidth=_,o.strokeStyle="rgba("+P+","+b+","+l+","+v/255+")",o.stroke(),d=!1,c=!0},this.fillColor=function(T,k,_,P){o.fillStyle="rgba("+T+","+k+","+_+","+P/255+")",o.fill(),d=!1,c=!0},this.strokeLayer=function(T,k,_,P){o.lineCap=T,o.lineJoin=k,o.lineWidth=_,o.strokeStyle=o.createPattern(P.getCanvas(),"repeat"),o.stroke(),d=!1,c=!0},this.fillLayer=function(T){o.fillStyle=o.createPattern(T.getCanvas(),"repeat"),o.fill(),d=!1,c=!0},this.push=function(){o.save(),x++},this.pop=function(){x>0&&(o.restore(),x--)},this.reset=function(){for(;x>0;)o.restore(),x--;o.restore(),o.save(),o.beginPath(),c=!1},this.setTransform=function(T,k,_,P,b,l){o.setTransform(T,k,_,P,b,l)},this.transform=function(T,k,_,P,b,l){o.transform(T,k,_,P,b,l)},this.setChannelMask=function(T){o.globalCompositeOperation=u[T]},this.setMiterLimit=function(T){o.miterLimit=T},y(r,e),s.style.zIndex=-1};n.Layer.ROUT=2;n.Layer.ATOP=6;n.Layer.XOR=10;n.Layer.ROVER=11;n.Layer.OVER=14;n.Layer.PLUS=15;n.Layer.RIN=1;n.Layer.IN=4;n.Layer.OUT=8;n.Layer.RATOP=9;n.Layer.SRC=12;n.Layer.Pixel=function(r,e,t,a){this.red=r,this.green=e,this.blue=t,this.alpha=a};var n=n||{};n.Mouse=function(e){n.Mouse.Event.Target.call(this);var t=this;this.touchMouseThreshold=3,this.scrollThreshold=53,this.PIXELS_PER_LINE=18,this.PIXELS_PER_PAGE=this.PIXELS_PER_LINE*16;var a=[n.Mouse.State.Buttons.LEFT,n.Mouse.State.Buttons.MIDDLE,n.Mouse.State.Buttons.RIGHT],s=0,o=0;e.addEventListener("contextmenu",function(u){n.Event.DOMEvent.cancelEvent(u)},!1),e.addEventListener("mousemove",function(u){if(s){n.Event.DOMEvent.cancelEvent(u),s--;return}t.move(n.Position.fromClientPosition(e,u.clientX,u.clientY),u)},!1),e.addEventListener("mousedown",function(u){if(s){n.Event.DOMEvent.cancelEvent(u);return}var y=a[u.button];y&&t.press(y,u)},!1),e.addEventListener("mouseup",function(u){if(s){n.Event.DOMEvent.cancelEvent(u);return}var y=a[u.button];y&&t.release(y,u)},!1),e.addEventListener("mouseout",function(u){u||(u=window.event);for(var y=u.relatedTarget||u.toElement;y;){if(y===e)return;y=y.parentNode}t.reset(u),t.out(u)},!1),e.addEventListener("selectstart",function(u){n.Event.DOMEvent.cancelEvent(u)},!1);function d(){s=t.touchMouseThreshold}e.addEventListener("touchmove",d,!1),e.addEventListener("touchstart",d,!1),e.addEventListener("touchend",d,!1);function c(u){var y=u.deltaY||-u.wheelDeltaY||-u.wheelDelta;if(y?u.deltaMode===1?y=u.deltaY*t.PIXELS_PER_LINE:u.deltaMode===2&&(y=u.deltaY*t.PIXELS_PER_PAGE):y=u.detail*t.PIXELS_PER_LINE,o+=y,o<=-t.scrollThreshold){do t.click(n.Mouse.State.Buttons.UP),o+=t.scrollThreshold;while(o<=-t.scrollThreshold);o=0}if(o>=t.scrollThreshold){do t.click(n.Mouse.State.Buttons.DOWN),o-=t.scrollThreshold;while(o>=t.scrollThreshold);o=0}n.Event.DOMEvent.cancelEvent(u)}window.WheelEvent?e.addEventListener("wheel",c,!1):(e.addEventListener("DOMMouseScroll",c,!1),e.addEventListener("mousewheel",c,!1));var x=(function(){var u=document.createElement("div");if(!("cursor"in u.style))return!1;try{u.style.cursor="url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX///+nxBvIAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==) 0 0, auto"}catch{return!1}return/\\burl\\([^()]*\\)\\s+0\\s+0\\b/.test(u.style.cursor||"")})();this.setCursor=function(u,y,w){if(x){var T=u.toDataURL("image/png");return e.style.cursor="url("+T+") "+y+" "+w+", auto",!0}return!1}};n.Mouse.State=function(e){var t=function(s,o,d,c,x,u,y){return{x:s,y:o,left:d,middle:c,right:x,up:u,down:y}};arguments.length>1?e=t.apply(this,arguments):e=e||{},n.Position.call(this,e),this.left=e.left||!1,this.middle=e.middle||!1,this.right=e.right||!1,this.up=e.up||!1,this.down=e.down||!1};n.Mouse.State.Buttons={LEFT:"left",MIDDLE:"middle",RIGHT:"right",UP:"up",DOWN:"down"};n.Mouse.Event=function(e,t,a){n.Event.DOMEvent.call(this,e,a);var s="on"+this.type;this.state=t,this.invokeLegacyHandler=function(d){d[s]&&(this.preventDefault(),this.stopPropagation(),d[s](this.state))}};n.Mouse.Event.Target=function(){n.Event.Target.call(this),this.currentState=new n.Mouse.State,this.press=function(t,a){this.currentState[t]||(this.currentState[t]=!0,this.dispatch(new n.Mouse.Event("mousedown",this.currentState,a)))},this.release=function(t,a){this.currentState[t]&&(this.currentState[t]=!1,this.dispatch(new n.Mouse.Event("mouseup",this.currentState,a)))},this.click=function(t,a){this.press(t,a),this.release(t,a)},this.move=function(t,a){(this.currentState.x!==t.x||this.currentState.y!==t.y)&&(this.currentState.x=t.x,this.currentState.y=t.y,this.dispatch(new n.Mouse.Event("mousemove",this.currentState,a)))},this.out=function(t){this.dispatch(new n.Mouse.Event("mouseout",this.currentState,t))},this.reset=function(t){for(var a in n.Mouse.State.Buttons)this.release(n.Mouse.State.Buttons[a],t)}};n.Mouse.Touchpad=function(e){n.Mouse.Event.Target.call(this);var t=this;this.scrollThreshold=20*(window.devicePixelRatio||1),this.clickTimingThreshold=250,this.clickMoveThreshold=10*(window.devicePixelRatio||1),this.currentState=new n.Mouse.State;var a=0,s=0,o=0,d=0,c=0,x={1:"left",2:"right",3:"middle"},u=!1,y=null;e.addEventListener("touchend",function(w){if(w.preventDefault(),u&&w.touches.length===0){var T=new Date().getTime(),k=x[a];t.currentState[k]&&(t.release(k,w),y&&(window.clearTimeout(y),y=null)),T-d<=t.clickTimingThreshold&&c<t.clickMoveThreshold&&(t.press(k,w),y=window.setTimeout(function(){t.release(k,w),u=!1},t.clickTimingThreshold)),y||(u=!1)}},!1),e.addEventListener("touchstart",function(w){if(w.preventDefault(),a=Math.min(w.touches.length,3),y&&(window.clearTimeout(y),y=null),!u){u=!0;var T=w.touches[0];s=T.clientX,o=T.clientY,d=new Date().getTime(),c=0}},!1),e.addEventListener("touchmove",function(w){w.preventDefault();var T=w.touches[0],k=T.clientX-s,_=T.clientY-o;if(c+=Math.abs(k)+Math.abs(_),a===1){var P=c/(new Date().getTime()-d),b=1+P,l=new n.Position(t.currentState);l.x+=k*b,l.y+=_*b,l.x=Math.min(Math.max(0,l.x),e.offsetWidth-1),l.y=Math.min(Math.max(0,l.y),e.offsetHeight-1),t.move(l,w),s=T.clientX,o=T.clientY}else if(a===2&&Math.abs(_)>=t.scrollThreshold){var v;_>0?v="down":v="up",t.click(v,w),s=T.clientX,o=T.clientY}},!1)};n.Mouse.Touchscreen=function(e){n.Mouse.Event.Target.call(this);var t=this,a=!1,s=null,o=null,d=null,c=null;this.scrollThreshold=20*(window.devicePixelRatio||1),this.clickTimingThreshold=250,this.clickMoveThreshold=16*(window.devicePixelRatio||1),this.longPressThreshold=500;function x(w){var T=w.touches[0]||w.changedTouches[0],k=T.clientX-s,_=T.clientY-o;return Math.sqrt(k*k+_*_)>=t.clickMoveThreshold}function u(w){var T=w.touches[0];a=!0,s=T.clientX,o=T.clientY}function y(){window.clearTimeout(d),window.clearTimeout(c),a=!1}e.addEventListener("touchend",function(w){if(a){if(w.touches.length!==0||w.changedTouches.length!==1){y();return}if(window.clearTimeout(c),t.release(n.Mouse.State.Buttons.LEFT,w),!x(w)&&(w.preventDefault(),!t.currentState.left)){var T=w.changedTouches[0];t.move(n.Position.fromClientPosition(e,T.clientX,T.clientY)),t.press(n.Mouse.State.Buttons.LEFT,w),d=window.setTimeout(function(){t.release(n.Mouse.State.Buttons.LEFT,w),y()},t.clickTimingThreshold)}}},!1),e.addEventListener("touchstart",function(w){if(w.touches.length!==1){y();return}w.preventDefault(),u(w),window.clearTimeout(d),c=window.setTimeout(function(){var T=w.touches[0];t.move(n.Position.fromClientPosition(e,T.clientX,T.clientY)),t.click(n.Mouse.State.Buttons.RIGHT,w),y()},t.longPressThreshold)},!1),e.addEventListener("touchmove",function(w){if(a){if(x(w)&&window.clearTimeout(c),w.touches.length!==1){y();return}if(t.currentState.left){w.preventDefault();var T=w.touches[0];t.move(n.Position.fromClientPosition(e,T.clientX,T.clientY),w)}}},!1)};var n=n||{},n=n||{};n.Object=function(e,t){var a=this,s={},o=function(x){var u=s[x];if(!u)return null;var y=u.shift();return u.length===0&&delete s[x],y},d=function(x,u){var y=s[x];y||(y=[],s[x]=y),y.push(u)};this.index=t,this.onbody=function(x,u,y){var w=o(y);w&&w(x,u)},this.onundefine=null,this.requestInputStream=function(x,u){u&&d(x,u),e.requestObjectInputStream(a.index,x)},this.createOutputStream=function(x,u){return e.createObjectOutputStream(a.index,x,u)}};n.Object.ROOT_STREAM="/";n.Object.STREAM_INDEX_MIMETYPE="application/vnd.glyptodon.guacamole.stream-index+json";var n=n||{};n.OnScreenKeyboard=function(r){var e=this,t={},a={},s=[],o=function(p,m){p.classList?p.classList.add(m):p.className+=" "+m},d=function(p,m){p.classList?p.classList.remove(m):p.className=p.className.replace(/([^ ]+)[ ]*/g,function(R,M){return M===m?"":R})},c=0,x=function(){c=e.touchMouseThreshold},u=function(p,m,S,R){this.width=m,this.height=S,this.scale=function(M){p.style.width=m*M+"px",p.style.height=S*M+"px",R&&(p.style.lineHeight=S*M+"px",p.style.fontSize=M+"px")}},y=function(p){for(var m=0;m<p.length;m++){var S=p[m];if(!(S in t))return!1}return!0},w=function(p){var m=e.keys[p];if(!m)return null;for(var S=m.length-1;S>=0;S--){var R=m[S];if(y(R.requires))return R}return null},T=function(p,m){if(!a[p]){o(m,"guac-keyboard-pressed");var S=w(p);if(S.modifier){var R="guac-keyboard-modifier-"+l(S.modifier),M=t[S.modifier];M===void 0?(o(_,R),t[S.modifier]=S.keysym,S.keysym&&e.onkeydown&&e.onkeydown(S.keysym)):(d(_,R),delete t[S.modifier],M&&e.onkeyup&&e.onkeyup(M))}else e.onkeydown&&e.onkeydown(S.keysym);a[p]=!0}},k=function(p,m){if(a[p]){d(m,"guac-keyboard-pressed");var S=w(p);!S.modifier&&e.onkeyup&&e.onkeyup(S.keysym),a[p]=!1}},_=document.createElement("div");_.className="guac-keyboard",_.onselectstart=_.onmousemove=_.onmouseup=_.onmousedown=function(p){return c&&c--,p.stopPropagation(),!1},this.touchMouseThreshold=3,this.onkeydown=null,this.onkeyup=null,this.layout=new n.OnScreenKeyboard.Layout(r),this.getElement=function(){return _},this.resize=function(g){for(var p=Math.floor(g*10/e.layout.width)/10,m=0;m<s.length;m++){var S=s[m];S.scale(p)}};var P=function(p,m){if(m instanceof Array){for(var S=[],R=0;R<m.length;R++)S.push(new n.OnScreenKeyboard.Key(m[R],p));return S}return typeof m=="number"?[new n.OnScreenKeyboard.Key({name:p,keysym:m})]:typeof m=="string"?[new n.OnScreenKeyboard.Key({name:p,title:m})]:[new n.OnScreenKeyboard.Key(m,p)]},b=function(p){var m={};for(var S in r.keys)m[S]=P(S,p[S]);return m};this.keys=b(r.keys);var l=function(p){var m=p.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[^A-Za-z0-9]+/g,"-").toLowerCase();return m},v=function g(p,m,S){var R,M=document.createElement("div");if(S&&o(M,"guac-keyboard-"+l(S)),m instanceof Array)for(o(M,"guac-keyboard-group"),R=0;R<m.length;R++)g(M,m[R]);else if(m instanceof Object){o(M,"guac-keyboard-group");var O=Object.keys(m).sort();for(R=0;R<O.length;R++){var S=O[R];g(M,m[S],S)}}else if(typeof m=="number")o(M,"guac-keyboard-gap"),s.push(new u(M,m,m));else if(typeof m=="string"){var F=m;F.length===1&&(F="0x"+F.charCodeAt(0).toString(16)),o(M,"guac-keyboard-key-container");var H=document.createElement("div");H.className="guac-keyboard-key guac-keyboard-key-"+l(F);var i=e.keys[m];if(i)for(R=0;R<i.length;R++){var f=i[R],h=document.createElement("div");h.className="guac-keyboard-cap",h.textContent=f.title;for(var C=0;C<f.requires.length;C++){var A=f.requires[C];o(h,"guac-keyboard-requires-"+l(A)),o(H,"guac-keyboard-uses-"+l(A))}H.appendChild(h)}M.appendChild(H),s.push(new u(M,e.layout.keyWidths[m]||1,1,!0));var L=function(Y){Y.preventDefault(),c=e.touchMouseThreshold,T(m,H)},I=function(Y){Y.preventDefault(),c=e.touchMouseThreshold,k(m,H)},E=function(Y){Y.preventDefault(),c===0&&T(m,H)},D=function(Y){Y.preventDefault(),c===0&&k(m,H)};H.addEventListener("touchstart",L,!0),H.addEventListener("touchend",I,!0),H.addEventListener("mousedown",E,!0),H.addEventListener("mouseup",D,!0),H.addEventListener("mouseout",D,!0)}p.appendChild(M)};v(_,r.layout)};n.OnScreenKeyboard.Layout=function(r){this.language=r.language,this.type=r.type,this.keys=r.keys,this.layout=r.layout,this.width=r.width,this.keyWidths=r.keyWidths||{}};n.OnScreenKeyboard.Key=function(r,e){this.name=e||r.name,this.title=r.title||this.name,this.keysym=r.keysym||(function(a){if(!a||a.length!==1)return null;var s=a.charCodeAt(0);return s>=0&&s<=255?s:s>=256&&s<=1114111?16777216|s:null})(this.title),this.modifier=r.modifier,this.requires=r.requires||[]};var n=n||{};n.OutputStream=function(r,e){var t=this;this.index=e,this.onack=null,this.sendBlob=function(a){r.sendBlob(t.index,a)},this.sendEnd=function(){r.endStream(t.index)}};var n=n||{};n.Parser=function(){var e=this,t="",a=[],s=-1,o=0,d=0,c=4096,x=65536;this.receive=function(y,w){for(w?t=y:(o>c&&s>=o&&(t=t.substring(o),s-=o,o=0),t.length?t+=y:t=y);s<t.length;){if(s>=o){var T=n.Parser.codePointCount(t,o,s);if(T<d){s+=d-T;continue}else if(d&&t.codePointAt(s-1)>=x){s++;continue}var k=t.substring(o,s),_=t.substring(s,s+1);if(a.push(k),_===";"){var P=a.shift();e.oninstruction!==null&&e.oninstruction(P,a),a=[],!w&&s+1===t.length&&(s=-1,t="")}else if(_!==",")throw new Error(\'Element terminator of instruction was not ";" nor ",".\');o=s+1}var b=t.indexOf(".",o);if(b!==-1){if(d=parseInt(t.substring(s+1,b)),isNaN(d))throw new Error("Non-numeric character in element length.");o=b+1,s=o+d}else{o=t.length;break}}},this.oninstruction=null};n.Parser.codePointCount=function(e,t,a){e=e.substring(t||0,a);var s=e.match(/[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g);return e.length-(s?s.length:0)};n.Parser.toInstruction=function(e){for(var t=function(d){var c=""+d;return n.Parser.codePointCount(c)+"."+c},a=t(e[0]),s=1;s<e.length;s++)a+=","+t(e[s]);return a+";"};var n=n||{};n.Position=function(e){e=e||{},this.x=e.x||0,this.y=e.y||0,this.fromClientPosition=function(a,s,o){this.x=s-a.offsetLeft,this.y=o-a.offsetTop;for(var d=a.offsetParent;d&&d!==document.body;)this.x-=d.offsetLeft-d.scrollLeft,this.y-=d.offsetTop-d.scrollTop,d=d.offsetParent;if(d){var c=document.body.scrollLeft||document.documentElement.scrollLeft,x=document.body.scrollTop||document.documentElement.scrollTop;this.x-=d.offsetLeft-c,this.y-=d.offsetTop-x}}};n.Position.fromClientPosition=function(e,t,a){var s=new n.Position;return s.fromClientPosition(e,t,a),s};var n=n||{};n.RawAudioFormat=function(e){this.bytesPerSample=e.bytesPerSample,this.channels=e.channels,this.rate=e.rate};n.RawAudioFormat.parse=function(e){var t,a=null,s=1;if(e.substring(0,9)==="audio/L8;")e=e.substring(9),t=1;else if(e.substring(0,10)==="audio/L16;")e=e.substring(10),t=2;else return null;for(var o=e.split(","),d=0;d<o.length;d++){var c=o[d],x=c.indexOf("=");if(x===-1)return null;var u=c.substring(0,x),y=c.substring(x+1);switch(u){case"channels":s=parseInt(y);break;case"rate":a=parseInt(y);break;default:return null}}return a===null?null:new n.RawAudioFormat({bytesPerSample:t,channels:s,rate:a})};var n=n||{};n.SessionRecording=function(e,t){t===void 0&&(t=1e3);var a=this,s,o=null,d=262144,c=16384,x=5e3,u=[],y=0,w=new n.SessionRecording._PlaybackTunnel,T=new n.Client(w),k=-1,_=null,P=null,b=0,l=null,v=0,g=0,p=!1,m=null,S=null,R=null,M=function(N,W,G){if(!(p&&N===s)){var X=new n.Parser;X.oninstruction=W;var V=0,J=new FileReader,ie=function(){if(!(p&&N===s)){if(J.readyState===2)try{X.receive(J.result)}catch(ne){a.onerror&&a.onerror(ne.message);return}if(V>=N.size)G&&G();else{var te=N.slice(V,V+d);V+=te.size,J.readAsText(te)}}};J.onload=ie,ie()}},O=function(U){for(var N=U.length,W=U.length-1;W>=0;W--){var G=U.charCodeAt(W);G>127&&G<=2047?N++:G>2047&&G<=65535&&(N+=2),G>=56320&&G<=57343&&W--}return N},F=function(N){for(var W=O(N)+3,G=n.Parser.codePointCount(N);G>=10;)W++,G=Math.floor(G/10);return W};T.connect(),T.getDisplay().showCursor(!1);var H=null;function i(U){H=new n.KeyEventInterpreter(U)}var f=function(N,W){g+=F(N);for(var G=0;G<W.length;G++)g+=F(W[G]);if(N==="sync"){var X=parseInt(W[0]),V=new n.SessionRecording._Frame(X,v,g);u.push(V),v=g,u.length===1&&i(X),(u.length===1||g-u[y].start>=c&&X-u[y].timestamp>=x)&&(V.keyframe=!0,y=u.length-1),a.onprogress&&a.onprogress(a.getDuration(),g)}else N==="key"&&H.handleKeyEvent(W)},h=function(){a.onload&&a.onload()};if(e instanceof Blob)s=e,M(s,f,h);else{o=e,s=new Blob;var C=!1,A="";o.oninstruction=function(N,W){A+=N.length+"."+N,W.forEach(function(X){A+=","+X.length+"."+X}),A+=";",A.length>=d&&(s=new Blob([s,A]),A=""),f(N,W)},o.onerror=function(N){C=!0,a.onerror&&a.onerror(N.message)},o.onstatechange=function(N){N===n.Tunnel.State.CLOSED&&(A.length&&(s=new Blob([s,A]),A=""),a.onkeyevents&&a.onkeyevents(H.getEvents()),C||h())}}var L=function(N){return u.length===0?0:N-u[0].timestamp},I=function U(N,W,G){if(N===W){if(N===0)return N;if(L(u[N].timestamp)>G)return N-1}var X=Math.floor((N+W)/2),V=L(u[X].timestamp);return G<V&&X>N?U(N,X-1,G):G>V&&X<W?U(X+1,W,G):X},E=function(N,W){var G=u[N];M(s.slice(G.start,G.end),function(V,J){w.receiveInstruction(V,J)},function(){G.keyframe&&!G.clientState&&T.exportState(function(J){G.clientState=new Blob([JSON.stringify(J)])}),k=N,W&&W()})},D=function(N,W,G){B();for(var X=l={aborted:!1},V=N,J=function te(){a.onseek&&k>V&&(b=L(u[k].timestamp),a.onseek(b,k-V,N-V)),!X.aborted&&(k<N?E(k+1,te):W())},ie=function(){var ne=G?Math.max(G-new Date().getTime(),0):0;ne?(S&&clearTimeout(S),S=window.setTimeout(function(){S=null,J()},ne)):J()};V>=0;V--){var he=u[V];if(V===k)break;if(he.clientState){he.clientState.text().then(function(ne){T.importState(JSON.parse(ne)),k=V,ie()});return}}ie()},B=function(){l&&(l.aborted=!0,l=null)},Y=function U(){if(a.isPlaying())if(k+1<u.length){var N=u[k+1],W=Date.now()-P,G=L(N.timestamp)-_,X=G-W,V=t>=0?t*Math.floor((b+t)/t)-b:X;X<=V?D(k+1,function(){R=Date.now(),U()},Date.now()+X):(S&&window.clearTimeout(S),S=window.setTimeout(function(){S=null,b+=V,a.onseek&&a.onseek(b),R=Date.now(),U()},V))}else a.pause()};this.onload=null,this.onerror=null,this.onabort=null,this.onprogress=null,this.onplay=null,this.onpause=null,this.onkeyevents=null,this.onseek=null,this.connect=function(N){o&&o.connect(N)},this.disconnect=function(){o&&o.disconnect()},this.abort=function(){p||(p=!0,a.onabort&&a.onabort(),o&&o.disconnect())},this.getDisplay=function(){return T.getDisplay()},this.isPlaying=function(){return!!P},this.getPosition=function(){return b},this.getDuration=function(){return u.length===0?0:L(u[u.length-1].timestamp)},this.play=function(){!a.isPlaying()&&k+1<u.length&&(a.onplay&&a.onplay(),_=b,P=Date.now(),R=Date.now(),Y())},this.seek=function(N,W){if(u.length!==0){a.cancel();var G=a.isPlaying();a.pause(),m=function(){m=null,G&&(a.play(),G=null),W&&W()};var X=I(0,u.length-1,N);D(X,function(){b=N,a.onseek&&a.onseek(N),m()})}},this.cancel=function(){m&&(B(),m())},this.pause=function(){B(),S&&clearTimeout(S),b+=Date.now()-R,a.isPlaying()&&(a.onpause&&a.onpause(),R=null,_=null,P=null)}};n.SessionRecording._Frame=function(e,t,a){this.keyframe=!1,this.timestamp=e,this.start=t,this.end=a,this.clientState=null};n.SessionRecording._PlaybackTunnel=function(){var e=this;this.connect=function(a){},this.sendMessage=function(a){},this.disconnect=function(){},this.receiveInstruction=function(a,s){e.oninstruction&&e.oninstruction(a,s)}};var n=n||{};n.Status=function(r,e){var t=this;this.code=r,this.message=e,this.isError=function(){return t.code<0||t.code>255}};n.Status.Code={SUCCESS:0,UNSUPPORTED:256,SERVER_ERROR:512,SERVER_BUSY:513,UPSTREAM_TIMEOUT:514,UPSTREAM_ERROR:515,RESOURCE_NOT_FOUND:516,RESOURCE_CONFLICT:517,RESOURCE_CLOSED:518,UPSTREAM_NOT_FOUND:519,UPSTREAM_UNAVAILABLE:520,SESSION_CONFLICT:521,SESSION_TIMEOUT:522,SESSION_CLOSED:523,CLIENT_BAD_REQUEST:768,CLIENT_UNAUTHORIZED:769,CLIENT_FORBIDDEN:771,CLIENT_TIMEOUT:776,CLIENT_OVERRUN:781,CLIENT_BAD_TYPE:783,CLIENT_TOO_MANY:797};n.Status.Code.fromHTTPCode=function(e){switch(e){case 400:return n.Status.Code.CLIENT_BAD_REQUEST;case 403:return n.Status.Code.CLIENT_FORBIDDEN;case 404:return n.Status.Code.RESOURCE_NOT_FOUND;case 429:return n.Status.Code.CLIENT_TOO_MANY;case 503:return n.Status.Code.SERVER_BUSY}return n.Status.Code.SERVER_ERROR};n.Status.Code.fromWebSocketCode=function(e){switch(e){case 1e3:return n.Status.Code.SUCCESS;case 1006:case 1015:return n.Status.Code.UPSTREAM_NOT_FOUND;case 1001:case 1012:case 1013:case 1014:return n.Status.Code.UPSTREAM_UNAVAILABLE}return n.Status.Code.SERVER_ERROR};var n=n||{};n.StringReader=function(r){var e=this,t=new n.UTF8Parser,a=new n.ArrayBufferReader(r);a.ondata=function(s){var o=t.decode(s);e.ontext&&e.ontext(o)},a.onend=function(){e.onend&&e.onend()},this.ontext=null,this.onend=null};var n=n||{};n.StringWriter=function(r){var e=this,t=new n.ArrayBufferWriter(r),a=new Uint8Array(8192),s=0;t.onack=function(x){e.onack&&e.onack(x)};function o(x){if(s+x>=a.length){var u=new Uint8Array((s+x)*2);u.set(a),a=u}s+=x}function d(x){var u,y;if(x<=127)u=0,y=1;else if(x<=2047)u=192,y=2;else if(x<=65535)u=224,y=3;else if(x<=2097151)u=240,y=4;else{d(65533);return}o(y);for(var w=s-1,T=1;T<y;T++)a[w--]=128|x&63,x>>=6;a[w]=u|x}function c(x){for(var u=0;u<x.length;u++){var y=x.charCodeAt(u);d(y)}if(s>0){var w=a.subarray(0,s);return s=0,w}}this.sendText=function(x){x.length&&t.sendData(c(x))},this.sendEnd=function(){t.sendEnd()},this.onack=null};var n=n||{};n.Touch=function(e){n.Event.Target.call(this);var t=this,a=new n.IntegerPool,s={},o=Math.floor(16*window.devicePixelRatio);this.touches={},this.activeTouches=0;var d=function(u){return u in s?s[u]:s[u]=a.next()},c=function(u){var y=d(u);return delete s[u],a.free(y),y};e.addEventListener("touchstart",function(u){for(var y=0;y<u.changedTouches.length;y++){var w=u.changedTouches[y],T=d(w.identifier);if(!t.touches[T]){var k=t.touches[T]=new n.Touch.State({id:T,radiusX:w.radiusX||o,radiusY:w.radiusY||o,angle:w.angle||0,force:w.force||1});t.activeTouches++,k.fromClientPosition(e,w.clientX,w.clientY),t.dispatch(new n.Touch.Event("touchmove",u,k))}}},!1),e.addEventListener("touchmove",function(u){for(var y=0;y<u.changedTouches.length;y++){var w=u.changedTouches[y],T=d(w.identifier),k=t.touches[T];k&&(w.force&&(k.force=w.force),k.angle=w.angle||0,k.radiusX=w.radiusX||o,k.radiusY=w.radiusY||o,k.fromClientPosition(e,w.clientX,w.clientY),t.dispatch(new n.Touch.Event("touchmove",u,k)))}},!1),e.addEventListener("touchend",function(u){for(var y=0;y<u.changedTouches.length;y++){var w=u.changedTouches[y],T=c(w.identifier),k=t.touches[T];k&&(delete t.touches[T],t.activeTouches--,k.force=0,k.fromClientPosition(e,w.clientX,w.clientY),t.dispatch(new n.Touch.Event("touchend",u,k)))}},!1)};n.Touch.State=function(e){e=e||{},n.Position.call(this,e),this.id=e.id||0,this.radiusX=e.radiusX||0,this.radiusY=e.radiusY||0,this.angle=e.angle||0,this.force=e.force||1};n.Touch.Event=function(e,t,a){n.Event.DOMEvent.call(this,e,[t]),this.state=a};var n=n||{};n.Tunnel=function(){this.connect=function(r){},this.disconnect=function(){},this.sendMessage=function(r){},this.setState=function(r){r!==this.state&&(this.state=r,this.onstatechange&&this.onstatechange(r))},this.setUUID=function(e){this.uuid=e,this.onuuid&&this.onuuid(e)},this.isConnected=function(){return this.state===n.Tunnel.State.OPEN||this.state===n.Tunnel.State.UNSTABLE},this.state=n.Tunnel.State.CLOSED,this.receiveTimeout=15e3,this.unstableThreshold=1500,this.uuid=null,this.onuuid=null,this.onerror=null,this.onstatechange=null,this.oninstruction=null};n.Tunnel.INTERNAL_DATA_OPCODE="";n.Tunnel.State={CONNECTING:0,OPEN:1,CLOSED:2,UNSTABLE:3};n.HTTPTunnel=function(r,e,t){var a=this,s=r+"?connect",o=r+"?read:",d=r+"?write:",c=1,x=0,u=c,y=!1,w="",T=!!e,k=null,_=null,P=null,b=500,l=t||{},v="Guacamole-Tunnel-Token",g=null;function p(i,f){for(var h in f)i.setRequestHeader(h,f[h])}var m=function(){window.clearTimeout(k),window.clearTimeout(_),a.state===n.Tunnel.State.UNSTABLE&&a.setState(n.Tunnel.State.OPEN),k=window.setTimeout(function(){S(new n.Status(n.Status.Code.UPSTREAM_TIMEOUT,"Server timeout."))},a.receiveTimeout),_=window.setTimeout(function(){a.setState(n.Tunnel.State.UNSTABLE)},a.unstableThreshold)};function S(i){window.clearTimeout(k),window.clearTimeout(_),window.clearInterval(P),a.state!==n.Tunnel.State.CLOSED&&(i.code!==n.Status.Code.SUCCESS&&a.onerror&&(a.state===n.Tunnel.State.CONNECTING||i.code!==n.Status.Code.RESOURCE_NOT_FOUND)&&a.onerror(i),y=!1,a.setState(n.Tunnel.State.CLOSED))}this.sendMessage=function(){a.isConnected()&&arguments.length&&(w+=n.Parser.toInstruction(arguments),y||R())};function R(){if(a.isConnected())if(w.length>0){y=!0;var i=new XMLHttpRequest;i.open("POST",d+a.uuid),i.withCredentials=T,p(i,l),i.setRequestHeader("Content-type","application/octet-stream"),i.setRequestHeader(v,g),i.onreadystatechange=function(){i.readyState===4&&(m(),i.status!==200?M(i):R())},i.send(w),w=""}else y=!1}function M(i){var f=parseInt(i.getResponseHeader("Guacamole-Status-Code"));if(f){var h=i.getResponseHeader("Guacamole-Error-Message");S(new n.Status(f,h))}else i.status?S(new n.Status(n.Status.Code.fromHTTPCode(i.status),i.statusText)):S(new n.Status(n.Status.Code.UPSTREAM_NOT_FOUND))}function O(i){var f=null,h=null,C=0,A=new n.Parser;A.oninstruction=function I(E,D){E===n.Tunnel.INTERNAL_DATA_OPCODE&&D.length===0?(A=new n.Parser,A.oninstruction=I,f&&clearInterval(f),i.onreadystatechange=null,i.abort(),h&&O(h)):E!==n.Tunnel.INTERNAL_DATA_OPCODE&&a.oninstruction&&a.oninstruction(E,D)};function L(){if(!a.isConnected()){f!==null&&clearInterval(f);return}if(!(i.readyState<2)){var I;try{I=i.status}catch{I=200}if(!h&&I===200&&(h=H()),i.readyState===3||i.readyState===4){if(m(),u===c&&(i.readyState===3&&!f?f=setInterval(L,30):i.readyState===4&&f&&clearInterval(f)),i.status===0){a.disconnect();return}else if(i.status!==200){M(i);return}var E;try{E=i.responseText}catch{return}try{A.receive(E,!0)}catch(D){S(new n.Status(n.Status.Code.SERVER_ERROR,D.message));return}}}}u===c?i.onreadystatechange=function(){i.readyState===3&&(C++,C>=2&&(u=x,i.onreadystatechange=L)),L()}:i.onreadystatechange=L,L()}var F=0;function H(){var i=new XMLHttpRequest;return i.open("GET",o+a.uuid+":"+F++),i.setRequestHeader(v,g),i.withCredentials=T,p(i,l),i.send(null),i}this.connect=function(i){m(),a.setState(n.Tunnel.State.CONNECTING);var f=new XMLHttpRequest;f.onreadystatechange=function(){if(f.readyState===4){if(f.status!==200){M(f);return}if(m(),a.setUUID(f.responseText),g=f.getResponseHeader(v),!g){S(new n.Status(n.Status.Code.UPSTREAM_NOT_FOUND));return}a.setState(n.Tunnel.State.OPEN),P=setInterval(function(){a.sendMessage("nop")},b),O(H())}},f.open("POST",s,!0),f.withCredentials=T,p(f,l),f.setRequestHeader("Content-type","application/x-www-form-urlencoded; charset=UTF-8"),f.send(i)},this.disconnect=function(){S(new n.Status(n.Status.Code.SUCCESS,"Manually closed."))}};n.HTTPTunnel.prototype=new n.Tunnel;n.WebSocketTunnel=function(r){var e=this,t=null,a=null,s=null,o=null,d=null,c={"http:":"ws:","https:":"wss:"},x=500,u=0;if(r.substring(0,3)!=="ws:"&&r.substring(0,4)!=="wss:"){var y=c[window.location.protocol];if(r.substring(0,1)==="/")r=y+"//"+window.location.host+r;else{var w=window.location.pathname.lastIndexOf("/"),T=window.location.pathname.substring(0,w+1);r=y+"//"+window.location.host+T+r}}var k=function(){var l=new Date().getTime();e.sendMessage(n.Tunnel.INTERNAL_DATA_OPCODE,"ping",l),u=l},_=function(){window.clearTimeout(s),window.clearTimeout(o),window.clearTimeout(d),e.state===n.Tunnel.State.UNSTABLE&&e.setState(n.Tunnel.State.OPEN),s=window.setTimeout(function(){P(new n.Status(n.Status.Code.UPSTREAM_TIMEOUT,"Server timeout."))},e.receiveTimeout),o=window.setTimeout(function(){e.setState(n.Tunnel.State.UNSTABLE)},e.unstableThreshold);var l=new Date().getTime(),v=Math.max(u+x-l,0);v>0?d=window.setTimeout(k,v):k()};function P(b){window.clearTimeout(s),window.clearTimeout(o),window.clearTimeout(d),e.state!==n.Tunnel.State.CLOSED&&(b.code!==n.Status.Code.SUCCESS&&e.onerror&&e.onerror(b),e.setState(n.Tunnel.State.CLOSED),a.close())}this.sendMessage=function(b){e.isConnected()&&arguments.length&&a.send(n.Parser.toInstruction(arguments))},this.connect=function(b){_(),e.setState(n.Tunnel.State.CONNECTING),t=new n.Parser,t.oninstruction=function(v,g){e.uuid===null&&(v===n.Tunnel.INTERNAL_DATA_OPCODE&&g.length===1&&e.setUUID(g[0]),e.setState(n.Tunnel.State.OPEN)),v!==n.Tunnel.INTERNAL_DATA_OPCODE&&e.oninstruction&&e.oninstruction(v,g)},a=new WebSocket(r+"?"+b,"guacamole"),a.onopen=function(l){_()},a.onclose=function(l){l.reason?P(new n.Status(parseInt(l.reason),l.reason)):l.code?P(new n.Status(n.Status.Code.fromWebSocketCode(l.code))):P(new n.Status(n.Status.Code.UPSTREAM_NOT_FOUND))},a.onmessage=function(l){_();try{t.receive(l.data)}catch(v){P(new n.Status(n.Status.Code.SERVER_ERROR,v.message))}}},this.disconnect=function(){P(new n.Status(n.Status.Code.SUCCESS,"Manually closed."))}};n.WebSocketTunnel.prototype=new n.Tunnel;n.ChainedTunnel=function(r){for(var e=this,t,a=[],s=null,o=0;o<arguments.length;o++)a.push(arguments[o]);function d(c){e.disconnect=c.disconnect,e.sendMessage=c.sendMessage;var x=function(w){if(w&&w.code===n.Status.Code.UPSTREAM_TIMEOUT)return a=[],null;var T=a.shift();return T&&(c.onerror=null,c.oninstruction=null,c.onstatechange=null,d(T)),T};function u(){c.onstatechange=e.onstatechange,c.oninstruction=e.oninstruction,c.onerror=e.onerror,c.uuid&&e.setUUID(c.uuid),c.onuuid=function(w){e.setUUID(w)},s=c}c.onstatechange=function(y){switch(y){case n.Tunnel.State.OPEN:u(),e.onstatechange&&e.onstatechange(y);break;case n.Tunnel.State.CLOSED:!x()&&e.onstatechange&&e.onstatechange(y);break}},c.oninstruction=function(y,w){u(),e.oninstruction&&e.oninstruction(y,w)},c.onerror=function(y){!x(y)&&e.onerror&&e.onerror(y)},c.connect(t)}this.connect=function(c){t=c;var x=s||a.shift();x?d(x):e.onerror&&e.onerror(n.Status.Code.SERVER_ERROR,"No tunnels to try.")}};n.ChainedTunnel.prototype=new n.Tunnel;n.StaticHTTPTunnel=function(e,t,a){var s=this,o=null,d=a||{};this.size=null,this.sendMessage=function(x){},this.connect=function(x){s.disconnect(),s.setState(n.Tunnel.State.CONNECTING);var u=new n.Parser,y=new n.UTF8Parser;u.oninstruction=function(T,k){s.oninstruction&&s.oninstruction(T,k)},o=new AbortController,fetch(e,{headers:d,credentials:t?"include":"same-origin",signal:o.signal}).then(function(T){if(!T.ok){s.onerror&&s.onerror(new n.Status(n.Status.Code.fromHTTPCode(T.status),T.statusText)),s.disconnect();return}s.size=T.headers.get("Content-Length"),s.setState(n.Tunnel.State.OPEN);var k=T.body.getReader(),_=function P(b){if(b.done){s.disconnect();return}u.receive(y.decode(b.value)),k.read().then(P)};k.read().then(_)})},this.disconnect=function(){o&&(o.abort(),o=null),s.setState(n.Tunnel.State.CLOSED)}};n.StaticHTTPTunnel.prototype=new n.Tunnel;var n=n||{};n.UTF8Parser=function(){var e=0,t=0;this.decode=function(s){for(var o="",d=new Uint8Array(s),c=0;c<d.length;c++){var x=d[c];e===0?(x|127)===127?o+=String.fromCharCode(x):(x|31)===223?(t=x&31,e=1):(x|15)===239?(t=x&15,e=2):(x|7)===247?(t=x&7,e=3):o+="\\uFFFD":(x|63)===191?(t=t<<6|x&63,e--,e===0&&(o+=String.fromCharCode(t))):(e=0,o+="\\uFFFD")}return o}};var n=n||{};n.API_VERSION="1.6.0";var n=n||{};n.VideoPlayer=function(){this.sync=function(){}};n.VideoPlayer.isSupportedType=function(e){return!1};n.VideoPlayer.getSupportedTypes=function(){return[]};n.VideoPlayer.getInstance=function(e,t,a){return null};typeof window<"u"&&(window.Guacamole=n);function Ue(r){return r===517||r===521?"conflict":r===519||r===520?"unreachable":"other"}function ke(r,e,t){let a=window.Guacamole,[s,o=""]=r.split("?",2),d=new a.WebSocketTunnel(s),c=new a.Client(d),x=c.getDisplay(),u=x.getElement();e.replaceChildren(u);let y=()=>{let b=x.getWidth();b>0&&x.scale(e.clientWidth/b)};x.onresize=y;let w=new ResizeObserver(y);w.observe(e);let T=!1,k=!1,_=(b,l)=>{T||(T=!0,w.disconnect(),t.lost(b,k?Ue(l):"blocked"))};d.onerror=b=>_(b.message||`Tunnel error ${b.code}`,b.code),c.onerror=b=>_(b.message||`Client error ${b.code}`,b.code),c.onstatechange=b=>{b===3?t.connected():b===5&&_("Disconnected")};let P=window.WebSocket;window.WebSocket=class extends P{constructor(b,l){super(b,l),this.addEventListener("open",()=>k=!0)}};try{c.connect(o)}finally{window.WebSocket=P}return{close:(b=!1)=>{let l;if(b&&x.getWidth()>0&&x.getHeight()>0)try{l=x.flatten().toDataURL("image/jpeg",.7),pe(e,l)}catch{l=void 0}l||e.replaceChildren(),T=!0,w.disconnect(),c.onstatechange=null,c.onerror=null,d.onerror=null;try{c.disconnect()}catch{}return l}}}function pe(r,e){let t=new Image;t.src=e,t.alt="The last frame of the computer screen",r.replaceChildren(t)}var ye={sessionId:null,status:"starting",steps:[],text:""},Fe=200;function be(r){let e=r.replace(/^mcp__[^_]+__/,"").replace(/[_-]+/g," ").trim();return e?e.charAt(0).toUpperCase()+e.slice(1):r}var Be=/^\\[[A-Za-z ]+\\]/,Ce=160;function Ke(r){if(!/^[[{]/.test(r))return!1;try{return typeof JSON.parse(r)=="object"}catch{return/^(\\[\\s*[{"\\]]|\\{\\s*")/.test(r)}}function He(r){let e=r.trim();return!e||Be.test(e)||Ke(e)?null:e.length>Ce?`${e.slice(0,Ce-1)}\\u2026`:e}function Ge(r){let e=r?.title;return typeof e=="string"&&e.trim()?e.trim():void 0}function ze(r,e){let t=[...r],a=()=>t.at(-1),s=o=>t.find(d=>d.callId===o);for(let o of e)if(o.type==="tool-input-start")o.toolName!=="execute"&&!s(o.toolCallId)&&t.push({title:be(o.toolName),callId:o.toolCallId});else if(o.type==="tool-input-available"){let d=Ge(o.input)??(o.toolName==="execute"?void 0:be(o.toolName));if(!d)continue;let c=s(o.toolCallId);c?c.title=d:t.push({title:d,callId:o.toolCallId})}else if((o.type==="data-progress"||o.type==="data-status")&&o.data?.text){let d=He(o.data.text),c=a();if(!d||d===c?.title||d===c?.detail)continue;c?.callId?t[t.length-1]={...c,detail:d}:t.push({title:d})}return t}function _e(r){let e=s=>s.replace(/[&<>"\']/g,o=>({"&":"&","<":"<",">":">",\'"\':""","\'":"'"})[o]),t=[],a=r.replace(/\\uE000/g,"").replace(/`([^`\\n]+)`/g,(s,o)=>(t.push(`<code>${e(o)}</code>`),`\\uE000${t.length-1}\\uE000`));return e(a).replace(/\\*\\*([^\\n]+?)\\*\\*/g,"<strong>$1</strong>").replace(/\\uE000(\\d+)\\uE000/g,(s,o)=>t[Number(o)])}function Ie(r,e){let t=ze(r.steps,e.events??[]);return{...r,status:e.status,steps:t.slice(-Fe),text:e.text??r.text,approval:e.status==="needs_approval"?e.approval:void 0,error:e.error,playgroundUrl:e.playground_url??r.playgroundUrl}}function j(r){return r.status==="idle"||r.status==="error"}function Ae(r){return r.status==="starting"?"Starting Sai\\u2026":r.status==="needs_approval"?"Sai needs your OK to continue":r.status==="error"?"Sai stopped with an error":r.status==="idle"?"Done":r.steps.at(-1)?.title??"Sai is working\\u2026"}var q=window.parent===window?new oe:new ae;q instanceof oe&&document.documentElement.classList.add("standalone");var K=ye,ce,ge=!1,ve=null,ue=null,le=null,$,se=null,me=!1,ee="inline",de=[],We=new Set(["Claude"]),Pe="",re=r=>new Promise(e=>setTimeout(e,r)),z=r=>document.getElementById(r),Re=r=>r.replace(/[&<>"\']/g,e=>({"&":"&","<":"<",">":">",\'"\':""","\'":"'"})[e]);function Z(){z("headline").textContent=Ae(K),z("dot").className=`dot ${K.status}`;let r=K.steps.slice(-12);z("steps").innerHTML=r.map(t=>`<li>${Re(t.title)}${t.detail?`<span class="detail">${Re(t.detail)}</span>`:""}</li>`).join(""),z("steps-more").textContent=K.steps.length>r.length?`${K.steps.length-r.length} earlier steps`:"",z("answer").hidden=!(j(K)&&K.text),z("answer").innerHTML=_e(K.text),z("error").hidden=!K.error,z("error").textContent=K.error??"";let e=K.approval;z("approval").hidden=!e,e&&(z("approval-title").textContent=e.title,z("approval-text").textContent=e.command?`${e.description}\n${e.command}`:e.description,z("approve").hidden=z("approve-task").hidden=z("deny").hidden=e.isLinkOnly,z("open-approval").hidden=!e.isLinkOnly||!e.approvalUrl),z("live").hidden=!K.playgroundUrl,z("screen-wrap").hidden=!ve||j(K)&&!$&&!se,z("screen").hidden=xe&&!$,document.documentElement.dataset.mode=ee,z("pin").hidden=ee!=="inline"||!de.includes("pip"),z("expand").hidden=ee!=="inline"||!de.includes("fullscreen"),z("restore").hidden=ee==="inline",z("watch-here").hidden=!fe||j(K),z("popout").hidden=!(q instanceof ae)||!le||de.includes("pip")||!We.has(Pe),q.sizeChanged(document.documentElement.scrollHeight)}function we(r){if(r.structuredContent)return r.structuredContent;let e=r.content?.find(t=>t.type==="text")?.text;try{return e?JSON.parse(e):void 0}catch{return}}function Me(r,e){r?(K={...K,status:r.status,steps:r.steps,text:r.text,error:r.error},r.frame&&($=r.frame,pe(z("screen"),r.frame))):K={...K,status:"idle",text:e??""},Z()}function Le(){if(!ue)return;let r={status:K.status,steps:K.steps.map(({title:e,detail:t})=>({title:e,...t&&{detail:t}})),text:K.text,...K.error&&{error:K.error},...$&&{frame:$}};q.callTool("sai_view_save",{task_id:ue,snapshot:r}).catch(()=>{})}async function De(r){if(ge||!K.sessionId)return;ge=!0;let e=!0,t=a=>{e&&r(a),e=!1};try{for(;K.sessionId&&!j(K);){let a=Date.now(),s=await q.callTool("sai_view_poll",{session_id:K.sessionId,...ce&&{cursor:ce},...ue&&{task_id:ue}}),o=we(s);if(s.isError||!o){await re(5e3);continue}if(o.archived||o.expired){K={...K,playgroundUrl:o.playground_url??K.playgroundUrl},Me(o.saved,o.archived?"Sai has started another task on this computer since; this one has ended.":"This task\'s details are no longer available (Sai was restarted)."),t(!1);return}ce=o.cursor,K=Ie(K,o),e&&j(K)&&o.saved&&Me({...o.saved,status:K.status}),Z(),t(!j(K)),j(K)||await re(Math.max(0,4e3-(Date.now()-a)))}Le()}finally{ge=!1}}function Q(r){z("screen-note").textContent=r,z("screen-note").hidden=!r}async function Ve(){for(;!j(K);)await re(1e3);return"done"}var fe=!1,xe=!1;async function Oe(){if(me||!ve)return;me=!0,fe=!1,Z();let r=3e3,e=0;try{for(;!j(K)&&!fe;){let t=await q.callTool("sai_view_live",{machine_id:ve}).catch(()=>null),a=t&&!t.isError?we(t):void 0,s=typeof a?.websocket_url=="string"?a.websocket_url:null;if(!s){Q("Waiting for the computer to start\\u2026"),await re(8e3);continue}Q("Connecting to the computer\\u2026");let o,d=new Promise(x=>{o=ke(s,z("screen"),{connected:()=>{r=3e3,Q("")},lost:(u,y)=>x(y)})});se=o;let c=await Promise.race([d,Ve()]);if(j(K))break;if($=o.close(!0)??$,se=null,c==="conflict"){fe=!0;break}if(c==="blocked"&&++e>=2){Q(le?"This app keeps the card offline, so the screen can\'t show here. Open the live view link in the chat, or the Playground.":"This app keeps the card offline, so the screen can\'t show here. Watch it in the Playground."),xe=!0;break}if(c==="unreachable"){Q("Waiting for the computer to wake up\\u2026"),await re(8e3);continue}Q("Reconnecting\\u2026"),await re(r),r=Math.min(r*2,3e4)}}finally{$=se?.close(!0)??$,se=null,me=!1,xe||Q(fe&&!j(K)?"Being watched somewhere else.":""),$&&j(K)&&Le(),Z()}}async function Se(r){let e=K.approval;e&&(K={...K,approval:void 0,status:"running"},Z(),await q.callTool("sai_task_approve",{approval_id:e.approvalId,decision:r}).catch(()=>{}),De(()=>{}))}q.onToolResult=r=>{let e=we(r),t=typeof e?.session_id=="string"?e.session_id:null;!t||t===K.sessionId||(K={...ye,sessionId:t,status:"running"},ce=void 0,ve=typeof e?.machine_id=="string"?e.machine_id:null,ue=typeof e?.task_id=="string"?e.task_id:null,le=typeof e?.watch_url=="string"?e.watch_url:null,Z(),De(a=>{a&&Oe()}))};function Ne(r){r&&(r.theme&&(document.documentElement.dataset.theme=r.theme),r.availableDisplayModes&&(de=r.availableDisplayModes),r.displayMode&&(ee=r.displayMode),Z())}q.onHostContext=Ne;async function Te(r){ee=await q.requestDisplayMode(r).catch(()=>ee),Z()}z("pin").onclick=()=>{Te("pip")};z("watch-here").onclick=()=>{Oe()};z("popout").onclick=()=>le&&q.openLink(le);z("expand").onclick=()=>{Te("fullscreen")};z("restore").onclick=()=>{Te("inline")};z("approve").onclick=()=>{Se("approve")};z("approve-task").onclick=()=>{Se("approve_for_task")};z("deny").onclick=()=>{Se("deny")};z("open-approval").onclick=()=>K.approval?.approvalUrl&&q.openLink(K.approval.approvalUrl);z("live").onclick=()=>K.playgroundUrl&&q.openLink(K.playgroundUrl);q.connect("0.4.0").then(r=>{Pe=r.hostInfo?.name??"",Ne(r.hostContext),Z()}).catch(()=>Z());})();\n\n </script>\n </body>\n</html>\n' : "<!doctype html><html><body><p>Sai task view (build with npm run build)</p></body></html>";
|
|
22782
|
+
return true ? '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="utf-8" />\n <meta name="viewport" content="width=device-width, initial-scale=1" />\n <title>Sai task</title>\n <style>\n :root {\n --bg: #fff;\n --fg: #1b1b1b;\n --muted: #6b6b6b;\n --line: #e5e5e5;\n --card: #f6f6f4;\n --accent: #1b1b1b;\n --accent-fg: #fff;\n --ok: #2f9e44;\n --warn: #e8a317;\n --err: #d64545;\n }\n @media (prefers-color-scheme: dark) {\n :root:not([data-theme=\'light\']) {\n --bg: #161616;\n --fg: #eee;\n --muted: #9a9a9a;\n --line: #2c2c2c;\n --card: #1f1f1f;\n --accent: #eee;\n --accent-fg: #111;\n }\n }\n :root[data-theme=\'dark\'] {\n --bg: #161616;\n --fg: #eee;\n --muted: #9a9a9a;\n --line: #2c2c2c;\n --card: #1f1f1f;\n --accent: #eee;\n --accent-fg: #111;\n }\n * {\n box-sizing: border-box;\n }\n body {\n margin: 0;\n padding: 14px 16px;\n font:\n 13.5px/1.5 system-ui,\n -apple-system,\n sans-serif;\n color: var(--fg);\n background: var(--bg);\n }\n header {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .brand {\n font-weight: 600;\n }\n .modes {\n margin-left: auto;\n display: flex;\n gap: 6px;\n }\n button.mode {\n padding: 2px 8px;\n font-size: 12px;\n }\n /* Picture-in-picture: just the screen, the status and any approval. */\n [data-mode=\'pip\'] #steps,\n [data-mode=\'pip\'] #steps-more,\n [data-mode=\'pip\'] #answer,\n [data-mode=\'pip\'] #live {\n display: none;\n }\n [data-mode=\'pip\'] body {\n padding: 8px 10px;\n }\n #headline {\n color: var(--muted);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n flex: 1;\n }\n .dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: var(--muted);\n flex: none;\n }\n .dot.running,\n .dot.starting {\n background: var(--ok);\n animation: pulse 1.2s ease-in-out infinite;\n }\n .dot.needs_approval {\n background: var(--warn);\n }\n .dot.error {\n background: var(--err);\n }\n @keyframes pulse {\n 50% {\n opacity: 0.35;\n }\n }\n ol {\n margin: 10px 0 0;\n padding-left: 20px;\n color: var(--muted);\n }\n ol li:last-child {\n color: var(--fg);\n }\n #steps-more {\n color: var(--muted);\n font-size: 12px;\n margin-top: 4px;\n }\n .card {\n margin-top: 12px;\n padding: 10px 12px;\n border: 1px solid var(--line);\n border-radius: 10px;\n background: var(--card);\n }\n #approval-text,\n #answer,\n #error {\n white-space: pre-wrap;\n }\n #error {\n border-color: var(--err);\n }\n .row {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 8px;\n }\n button {\n font: inherit;\n padding: 5px 10px;\n border-radius: 7px;\n border: 1px solid var(--line);\n background: var(--bg);\n color: var(--fg);\n cursor: pointer;\n }\n button.primary {\n background: var(--accent);\n color: var(--accent-fg);\n border-color: var(--accent);\n }\n #live {\n margin-top: 12px;\n }\n /* Opened in a browser tab rather than inside a host\'s chat. */\n .standalone body {\n max-width: 960px;\n margin: 24px auto;\n }\n #answer code {\n font:\n 12px ui-monospace,\n SFMono-Regular,\n Menlo,\n monospace;\n padding: 1px 4px;\n border-radius: 4px;\n background: var(--line);\n }\n #steps .detail {\n display: block;\n color: var(--muted);\n font-size: 12px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n #screen-wrap {\n margin-top: 10px;\n }\n /* Guacamole sizes its own layers; the box keeps 16:9 before the first frame. */\n #screen {\n width: 100%;\n aspect-ratio: 16 / 9;\n background: #0b0d12;\n border-radius: 8px;\n overflow: hidden;\n }\n #screen img {\n width: 100%;\n display: block;\n }\n /* The screen has the keyboard: show it, so the person knows where keys go. */\n #screen > div:focus {\n outline: 2px solid var(--ok);\n outline-offset: -2px;\n }\n #screen-note,\n #input-note {\n margin-top: 4px;\n color: var(--muted);\n font-size: 12px;\n }\n </style>\n </head>\n <body>\n <header>\n <span id="dot" class="dot starting"></span><span class="brand">Sai</span\n ><span id="headline">Starting Sai\u2026</span>\n <span class="modes">\n <button id="pin" class="mode" hidden title="Keep this view on screen while you scroll">\n Keep visible\n </button>\n <button id="expand" class="mode" hidden title="Open full screen">Expand</button>\n <button\n id="popout"\n class="mode"\n hidden\n title="Watch in its own window while you keep chatting"\n >\n Open in a window \u2197\n </button>\n <button id="restore" class="mode" hidden title="Back into the conversation">\n Back to chat\n </button>\n </span>\n </header>\n <div id="screen-wrap" hidden>\n <div id="screen"></div>\n <div id="screen-note" hidden></div>\n <div id="input-note" hidden></div>\n <button id="watch-here" hidden title="Take the live screen back to this view">\n Watch here\n </button>\n <button id="use" hidden title="Connect to the computer and use its mouse and keyboard">\n Use this computer\n </button>\n <button id="stop-use" hidden title="Disconnect and keep the last frame">Done</button>\n </div>\n <ol id="steps"></ol>\n <div id="steps-more"></div>\n <div id="approval" class="card" hidden>\n <strong id="approval-title"></strong>\n <div id="approval-text"></div>\n <div class="row">\n <button id="approve" class="primary">Approve</button>\n <button id="approve-task">Approve for this task</button>\n <button id="deny">Deny</button>\n <button id="open-approval" class="primary" hidden>Open to finish</button>\n </div>\n </div>\n <div id="error" class="card" hidden></div>\n <div id="answer" class="card" hidden></div>\n <button id="live" hidden>Open in the Playground \u2197</button>\n <script>\n "use strict";(()=>{function Me(r){try{return["http:","https:"].includes(new URL(r).protocol)}catch{return!1}}var ue=class{constructor(e=window.parent){this.host=e;window.addEventListener("message",t=>this.receive(t))}host;nextId=1;pending=new Map;onToolInput;onToolResult;onHostContext;receive(e){if(e.source!==this.host)return;let t=e.data;if(!t||t.jsonrpc!=="2.0")return;if(typeof t.id=="number"&&("result"in t||"error"in t)){let s=this.pending.get(t.id);if(!s)return;this.pending.delete(t.id);let o=t.error;o?s.reject(new Error(o.message??"Host error")):s.resolve(t.result);return}let a=t.params??{};t.method==="ui/notifications/tool-input"?this.onToolInput?.(a.arguments??{}):t.method==="ui/notifications/tool-result"?this.onToolResult?.(a):t.method==="ui/notifications/host-context-changed"&&this.onHostContext?.(a),t.id!==void 0&&typeof t.method=="string"&&this.host.postMessage({jsonrpc:"2.0",id:t.id,result:{}},"*")}request(e,t){let a=this.nextId++;return new Promise((s,o)=>{this.pending.set(a,{resolve:s,reject:o}),this.host.postMessage({jsonrpc:"2.0",id:a,method:e,params:t},"*")})}notify(e,t){this.host.postMessage({jsonrpc:"2.0",method:e,params:t},"*")}async connect(e){let t=await this.request("ui/initialize",{protocolVersion:"2026-01-26",appInfo:{name:"Sai task",version:e},appCapabilities:{availableDisplayModes:["inline","pip","fullscreen"]}});return this.notify("ui/notifications/initialized",{}),t}async callTool(e,t){return await this.request("tools/call",{name:e,arguments:t})}openLink(e){Me(e)&&this.request("ui/open-link",{url:e}).catch(()=>{})}async requestDisplayMode(e){return(await this.request("ui/request-display-mode",{mode:e})).mode??e}sizeChanged(e){this.notify("ui/notifications/size-changed",{width:document.body.scrollWidth,height:e})}},le=class{onToolInput;onToolResult;onHostContext;params=new URLSearchParams(location.search);token=this.params.get("t")??"";async connect(e){let t=this.params.get("s"),a=this.params.get("m"),s=this.params.get("k");return t&&queueMicrotask(()=>this.onToolResult?.({structuredContent:{session_id:t,...a&&{machine_id:a},...s&&{task_id:s}}})),{}}async callTool(e,t){let a=await fetch("/tool",{method:"POST",headers:{"Content-Type":"application/json","x-sai-token":this.token},body:JSON.stringify({name:e,arguments:t})});return a.ok?await a.json():{isError:!0,content:[{type:"text",text:`HTTP ${a.status}`}]}}openLink(e){Me(e)&&window.open(e,"_blank","noopener,noreferrer")}async requestDisplayMode(e){return"inline"}sizeChanged(e){}};var n=n||{};n.ArrayBufferReader=function(r){var e=this;r.onblob=function(t){var a,s;if(Uint8Array.fromBase64)s=Uint8Array.fromBase64(t),a=s.buffer;else{var o=window.atob(t);a=new ArrayBuffer(o.length),s=new Uint8Array(a);for(var c=0;c<o.length;c++)s[c]=o.charCodeAt(c)}e.ondata&&e.ondata(a)},r.onend=function(){e.onend&&e.onend()},this.ondata=null,this.onend=null};var n=n||{};n.ArrayBufferWriter=function(r){var e=this;r.onack=function(a){e.onack&&e.onack(a)};function t(a){for(var s="",o=0;o<a.byteLength;o++)s+=String.fromCharCode(a[o]);r.sendBlob(window.btoa(s))}this.blobLength=n.ArrayBufferWriter.DEFAULT_BLOB_LENGTH,this.sendData=function(a){var s=new Uint8Array(a);if(s.length<=e.blobLength)t(s);else for(var o=0;o<s.length;o+=e.blobLength)t(s.subarray(o,o+e.blobLength))},this.sendEnd=function(){r.sendEnd()},this.onack=null};n.ArrayBufferWriter.DEFAULT_BLOB_LENGTH=6048;var n=n||{};n.AudioContextFactory={singleton:null,getAudioContext:function(){var e=window.AudioContext||window.webkitAudioContext;if(e)try{return n.AudioContextFactory.singleton||(n.AudioContextFactory.singleton=new e),n.AudioContextFactory.singleton}catch{}return null}};var n=n||{};n.AudioPlayer=function(){this.sync=function(){}};n.AudioPlayer.isSupportedType=function(e){return n.RawAudioPlayer.isSupportedType(e)};n.AudioPlayer.getSupportedTypes=function(){return n.RawAudioPlayer.getSupportedTypes()};n.AudioPlayer.getInstance=function(e,t){return n.RawAudioPlayer.isSupportedType(t)?new n.RawAudioPlayer(e,t):null};n.RawAudioPlayer=function(e,t){var a=n.RawAudioFormat.parse(t),s=n.AudioContextFactory.getAudioContext(),o=s.currentTime,c=new n.ArrayBufferReader(e),d=.02,m=.3,u=a.bytesPerSample===1?window.Int8Array:window.Int16Array,h=a.bytesPerSample===1?128:32768,S=[],E=function(v){if(v.length<=1)return v[0];var x=0;v.forEach(function(R){x+=R.length});var y=0,w=new u(x);return v.forEach(function(R){w.set(R,y),y+=R.length}),w},g=function(v){for(var x=Number.MAX_VALUE,y=v.length,w=Math.floor(v.length/a.channels),T=Math.floor(a.rate*d),R=Math.max(a.channels*T,a.channels*(w-T)),M=R;M<v.length;M+=a.channels){for(var D=0,F=0;F<a.channels;F++)D+=Math.abs(v[M+F]);D<=x&&(y=M+a.channels,x=D)}return y===v.length?[v]:[new u(v.buffer.slice(0,y*a.bytesPerSample)),new u(v.buffer.slice(y*a.bytesPerSample))]},I=function(v){S.push(new u(v))},P=function(){var v=E(S);return v?(S=g(v),v=S.shift(),v):null},C=function(v){var x=v.length/a.channels,y=s.currentTime;o<y&&(o=y);for(var w=s.createBuffer(a.channels,x,a.rate),T=0;T<a.channels;T++)for(var R=w.getChannelData(T),M=T,D=0;D<x;D++)R[D]=v[M]/h,M+=a.channels;return w};c.ondata=function(v){I(new u(v));var x=P();if(x){var y=s.currentTime;o<y&&(o=y);var w=s.createBufferSource();w.connect(s.destination),w.start||(w.start=w.noteOn),w.buffer=C(x),w.start(o),o+=x.length/a.channels/a.rate}},this.sync=function(){var v=s.currentTime;o=Math.min(o,v+m)}};n.RawAudioPlayer.prototype=new n.AudioPlayer;n.RawAudioPlayer.isSupportedType=function(e){return n.AudioContextFactory.getAudioContext()?n.RawAudioFormat.parse(e)!==null:!1};n.RawAudioPlayer.getSupportedTypes=function(){return n.AudioContextFactory.getAudioContext()?["audio/L8","audio/L16"]:[]};var n=n||{};n.AudioRecorder=function(){this.onclose=null,this.onerror=null};n.AudioRecorder.isSupportedType=function(e){return n.RawAudioRecorder.isSupportedType(e)};n.AudioRecorder.getSupportedTypes=function(){return n.RawAudioRecorder.getSupportedTypes()};n.AudioRecorder.getInstance=function(e,t){return n.RawAudioRecorder.isSupportedType(t)?new n.RawAudioRecorder(e,t):null};n.RawAudioRecorder=function(e,t){var a=this,s=2048,o=3,c=n.RawAudioFormat.parse(t),d=n.AudioContextFactory.getAudioContext();navigator.mediaDevices||(navigator.mediaDevices={}),navigator.mediaDevices.getUserMedia||(navigator.mediaDevices.getUserMedia=(navigator.getUserMedia||navigator.webkitGetUserMedia||navigator.mozGetUserMedia||navigator.msGetUserMedia).bind(navigator));var m=new n.ArrayBufferWriter(e),u=c.bytesPerSample===1?window.Int8Array:window.Int16Array,h=c.bytesPerSample===1?128:32768,S=0,E=0,g=null,I=null,P=null,C=function(D){if(D===0)return 1;var F=Math.PI*D;return Math.sin(F)/F},l=function(D,F){return-F<D&&D<F?C(D)*C(D/F):0},v=function(D,F){for(var H=(D.length-1)*F,i=Math.floor(H)-o+1,f=Math.floor(H)+o,p=0,k=i;k<=f;k++)p+=(D[k]||0)*l(H-k,o);return p},x=function(D){var F=D.length;S+=F;var H=Math.round(S*c.rate/D.sampleRate),i=H-E;E+=i;for(var f=new u(i*c.channels),p=0;p<c.channels;p++)for(var k=D.getChannelData(p),A=p,L=0;L<i;L++)f[A]=v(k,L/(i-1))*h,A+=c.channels;return f},y=function(D){P=d.createScriptProcessor(s,c.channels,c.channels),P.connect(d.destination),P.onaudioprocess=function(H){m.sendData(x(H.inputBuffer).buffer)},I=d.createMediaStreamSource(D),I.connect(P),d.state==="suspended"&&d.resume(),g=D},w=function(){m.sendEnd(),a.onerror&&a.onerror()},T=function(){var D=navigator.mediaDevices.getUserMedia({audio:!0},y,w);D&&D.then&&D.then(y,w)},R=function(){if(I&&I.disconnect(),P&&P.disconnect(),g)for(var D=g.getTracks(),F=0;F<D.length;F++)D[F].stop();P=null,I=null,g=null,m.sendEnd()};m.onack=function(D){D.code===n.Status.Code.SUCCESS&&!g?T():(R(),m.onack=null,D.code===n.Status.Code.RESOURCE_CLOSED?a.onclose&&a.onclose():a.onerror&&a.onerror())}};n.RawAudioRecorder.prototype=new n.AudioRecorder;n.RawAudioRecorder.isSupportedType=function(e){return n.AudioContextFactory.getAudioContext()?n.RawAudioFormat.parse(e)!==null:!1};n.RawAudioRecorder.getSupportedTypes=function(){return n.AudioContextFactory.getAudioContext()?["audio/L8","audio/L16"]:[]};var n=n||{};n.BlobReader=function(r,e){var t=this,a=0,s;window.BlobBuilder?s=new BlobBuilder:window.WebKitBlobBuilder?s=new WebKitBlobBuilder:window.MozBlobBuilder?s=new MozBlobBuilder:s=new(function(){var o=[];this.append=function(c){o.push(new Blob([c],{type:e}))},this.getBlob=function(){return new Blob(o,{type:e})}}),r.onblob=function(o){for(var c=window.atob(o),d=new ArrayBuffer(c.length),m=new Uint8Array(d),u=0;u<c.length;u++)m[u]=c.charCodeAt(u);s.append(d),a+=d.byteLength,t.onprogress&&t.onprogress(d.byteLength),r.sendAck("OK",0)},r.onend=function(){t.onend&&t.onend()},this.getLength=function(){return a},this.getBlob=function(){return s.getBlob()},this.onprogress=null,this.onend=null};var n=n||{};n.BlobWriter=function(e){var t=this,a=new n.ArrayBufferWriter(e);a.onack=function(o){t.onack&&t.onack(o)};var s=function(c,d,m){var u=(c.slice||c.webkitSlice||c.mozSlice).bind(c),h=m-d;if(h!==m){var S=u(d,h);if(S.size===h)return S}return u(d,m)};this.sendBlob=function(c){var d=0,m=function u(){if(d>=c.size){t.oncomplete&&t.oncomplete(c);return}var h=s(c,d,d+a.blobLength);d+=a.blobLength;var S=new FileReader;S.onload=function(){a.sendData(S.result),a.onack=function(I){t.onack&&t.onack(I),!I.isError()&&(t.onprogress&&t.onprogress(c,d-a.blobLength),u())}},S.onerror=function(){t.onerror&&t.onerror(c,d,S.error)},S.readAsArrayBuffer(h)};m()},this.sendEnd=function(){a.sendEnd()},this.onack=null,this.onerror=null,this.onprogress=null,this.oncomplete=null};var n=n||{};n.Client=function(r){var e=this,t=n.Client.State.IDLE,a=0,s=5e3,o=null,c=0,d={0:"butt",1:"round",2:"square"},m={0:"bevel",1:"miter",2:"round"},u=new n.Display,h={},S={},E={},g=[],I=[],P=[],C=new n.IntegerPool,l=[];function v(i){i!=t&&(t=i,e.onstatechange&&e.onstatechange(t))}function x(){return t==n.Client.State.CONNECTED||t==n.Client.State.WAITING}this.exportState=function(f){var p={currentState:t,currentTimestamp:a,layers:{}},k={};for(var A in h)k[A]=h[A];u.flush(function(){for(var _ in k){var b=parseInt(_),O=k[_],B={width:O.width,height:O.height};if(O.width&&O.height){var Y=O.toCanvas();B.url=Y.toDataURL("image/png")}b>0&&(B.x=O.x,B.y=O.y,B.z=O.z,B.alpha=O.alpha,B.matrix=O.matrix,B.parent=w(O.parent)),p.layers[_]=B}f(p)})},this.importState=function(f,p){var k,A;t=f.currentState,a=f.currentTimestamp,u.cancel();for(k in h)A=parseInt(k),A>0&&h[k].dispose();h={};for(k in f.layers){A=parseInt(k);var L=f.layers[k],_=y(A);if(u.resize(_,L.width,L.height),L.url&&(u.setChannelMask(_,n.Layer.SRC),u.draw(_,0,0,L.url)),A>0&&L.parent>=0){var b=y(L.parent);u.move(_,b,L.x,L.y,L.z),u.shade(_,L.alpha);var O=L.matrix;u.distort(_,O[0],O[1],O[2],O[3],O[4],O[5])}}u.flush(p)},this.getDisplay=function(){return u},this.sendSize=function(i,f){x()&&r.sendMessage("size",i,f)},this.sendKeyEvent=function(i,f){x()&&r.sendMessage("key",f,i)},this.sendMouseState=function(f,p){if(x()){var k=f.x,A=f.y;p&&(k/=u.getScale(),A/=u.getScale()),u.moveCursor(Math.floor(k),Math.floor(A));var L=0;f.left&&(L|=1),f.middle&&(L|=2),f.right&&(L|=4),f.up&&(L|=8),f.down&&(L|=16),r.sendMessage("mouse",Math.floor(k),Math.floor(A),L)}},this.sendTouchState=function(f,p){if(x()){var k=f.x,A=f.y;p&&(k/=u.getScale(),A/=u.getScale()),r.sendMessage("touch",f.id,Math.floor(k),Math.floor(A),Math.floor(f.radiusX),Math.floor(f.radiusY),f.angle,f.force)}},this.createOutputStream=function(){var f=C.next(),p=l[f]=new n.OutputStream(e,f);return p},this.createAudioStream=function(i){var f=e.createOutputStream();return r.sendMessage("audio",f.index,i),f},this.createFileStream=function(i,f){var p=e.createOutputStream();return r.sendMessage("file",p.index,i,f),p},this.createPipeStream=function(i,f){var p=e.createOutputStream();return r.sendMessage("pipe",p.index,i,f),p},this.createClipboardStream=function(i){var f=e.createOutputStream();return r.sendMessage("clipboard",f.index,i),f},this.createArgumentValueStream=function(f,p){var k=e.createOutputStream();return r.sendMessage("argv",k.index,f,p),k},this.createObjectOutputStream=function(f,p,k){var A=e.createOutputStream();return r.sendMessage("put",f,A.index,p,k),A},this.requestObjectInputStream=function(f,p){x()&&r.sendMessage("get",f,p)},this.sendAck=function(i,f,p){x()&&r.sendMessage("ack",i,f,p)},this.sendBlob=function(i,f){x()&&r.sendMessage("blob",i,f)},this.endStream=function(i){x()&&(r.sendMessage("end",i),l[i]&&(C.free(i),delete l[i]))},this.onstatechange=null,this.onname=null,this.onerror=null,this.onmsg=null,this.onjoin=null,this.onleave=null,this.onaudio=null,this.onvideo=null,this.onmultitouch=null,this.onargv=null,this.onclipboard=null,this.onfile=null,this.onfilesystem=null,this.onpipe=null,this.onrequired=null,this.onsync=null;var y=function(f){var p=h[f];return p||(f===0?p=u.getDefaultLayer():f>0?p=u.createLayer():p=u.createBuffer(),h[f]=p),p},w=function(f){if(!f)return null;for(var p in h)if(f===h[p])return parseInt(p);return null};function T(i){var f=g[i];return f==null&&(f=g[i]=new n.Parser,f.oninstruction=r.oninstruction),f}var R={"miter-limit":function(i,f){u.setMiterLimit(i,parseFloat(f))},"multi-touch":function(f,p){e.onmultitouch&&f instanceof n.Display.VisibleLayer&&e.onmultitouch(f,parseInt(p))}},M={ack:function(i){var f=parseInt(i[0]),p=i[1],k=parseInt(i[2]),A=l[f];A&&(A.onack&&A.onack(new n.Status(k,p)),k>=256&&l[f]===A&&(C.free(f),delete l[f]))},arc:function(i){var f=y(parseInt(i[0])),p=parseInt(i[1]),k=parseInt(i[2]),A=parseInt(i[3]),L=parseFloat(i[4]),_=parseFloat(i[5]),b=parseInt(i[6]);u.arc(f,p,k,A,L,_,b!=0)},argv:function(i){var f=parseInt(i[0]),p=i[1],k=i[2];if(e.onargv){var A=I[f]=new n.InputStream(e,f);e.onargv(A,p,k)}else e.sendAck(f,"Receiving argument values unsupported",256)},audio:function(i){var f=parseInt(i[0]),p=i[1],k=I[f]=new n.InputStream(e,f),A=null;e.onaudio&&(A=e.onaudio(k,p)),A||(A=n.AudioPlayer.getInstance(k,p)),A?(S[f]=A,e.sendAck(f,"OK",0)):e.sendAck(f,"BAD TYPE",783)},blob:function(i){var f=parseInt(i[0]),p=i[1],k=I[f];k&&k.onblob&&k.onblob(p)},body:function(f){var p=parseInt(f[0]),k=P[p],A=parseInt(f[1]),L=f[2],_=f[3];if(k&&k.onbody){var b=I[A]=new n.InputStream(e,A);k.onbody(b,L,_)}else e.sendAck(A,"Receipt of body unsupported",256)},cfill:function(i){var f=parseInt(i[0]),p=y(parseInt(i[1])),k=parseInt(i[2]),A=parseInt(i[3]),L=parseInt(i[4]),_=parseInt(i[5]);u.setChannelMask(p,f),u.fillColor(p,k,A,L,_)},clip:function(i){var f=y(parseInt(i[0]));u.clip(f)},clipboard:function(i){var f=parseInt(i[0]),p=i[1];if(e.onclipboard){var k=I[f]=new n.InputStream(e,f);e.onclipboard(k,p)}else e.sendAck(f,"Clipboard unsupported",256)},close:function(i){var f=y(parseInt(i[0]));u.close(f)},copy:function(i){var f=y(parseInt(i[0])),p=parseInt(i[1]),k=parseInt(i[2]),A=parseInt(i[3]),L=parseInt(i[4]),_=parseInt(i[5]),b=y(parseInt(i[6])),O=parseInt(i[7]),B=parseInt(i[8]);u.setChannelMask(b,_),u.copy(f,p,k,A,L,b,O,B)},cstroke:function(i){var f=parseInt(i[0]),p=y(parseInt(i[1])),k=d[parseInt(i[2])],A=m[parseInt(i[3])],L=parseInt(i[4]),_=parseInt(i[5]),b=parseInt(i[6]),O=parseInt(i[7]),B=parseInt(i[8]);u.setChannelMask(p,f),u.strokeColor(p,k,A,L,_,b,O,B)},cursor:function(i){var f=parseInt(i[0]),p=parseInt(i[1]),k=y(parseInt(i[2])),A=parseInt(i[3]),L=parseInt(i[4]),_=parseInt(i[5]),b=parseInt(i[6]);u.setCursor(f,p,k,A,L,_,b)},curve:function(i){var f=y(parseInt(i[0])),p=parseInt(i[1]),k=parseInt(i[2]),A=parseInt(i[3]),L=parseInt(i[4]),_=parseInt(i[5]),b=parseInt(i[6]);u.curveTo(f,p,k,A,L,_,b)},disconnect:function(f){e.disconnect()},dispose:function(i){var f=parseInt(i[0]);if(f>0){var p=y(f);u.dispose(p),delete h[f]}else f<0&&delete h[f]},distort:function(i){var f=parseInt(i[0]),p=parseFloat(i[1]),k=parseFloat(i[2]),A=parseFloat(i[3]),L=parseFloat(i[4]),_=parseFloat(i[5]),b=parseFloat(i[6]);if(f>=0){var O=y(f);u.distort(O,p,k,A,L,_,b)}},error:function(i){var f=i[0],p=parseInt(i[1]);e.onerror&&e.onerror(new n.Status(p,f)),e.disconnect()},end:function(i){var f=parseInt(i[0]),p=I[f];p&&(p.onend&&p.onend(),delete I[f])},file:function(i){var f=parseInt(i[0]),p=i[1],k=i[2];if(e.onfile){var A=I[f]=new n.InputStream(e,f);e.onfile(A,p,k)}else e.sendAck(f,"File transfer unsupported",256)},filesystem:function(f){var p=parseInt(f[0]),k=f[1];if(e.onfilesystem){var A=P[p]=new n.Object(e,p);e.onfilesystem(A,k)}},identity:function(i){var f=y(parseInt(i[0]));u.setTransform(f,1,0,0,1,0,0)},img:function(i){var f=parseInt(i[0]),p=parseInt(i[1]),k=y(parseInt(i[2])),A=i[3],L=parseInt(i[4]),_=parseInt(i[5]),b=I[f]=new n.InputStream(e,f);u.setChannelMask(k,p),u.drawStream(k,L,_,b,A)},jpeg:function(i){var f=parseInt(i[0]),p=y(parseInt(i[1])),k=parseInt(i[2]),A=parseInt(i[3]),L=i[4];u.setChannelMask(p,f),u.draw(p,k,A,"data:image/jpeg;base64,"+L)},lfill:function(i){var f=parseInt(i[0]),p=y(parseInt(i[1])),k=y(parseInt(i[2]));u.setChannelMask(p,f),u.fillLayer(p,k)},line:function(i){var f=y(parseInt(i[0])),p=parseInt(i[1]),k=parseInt(i[2]);u.lineTo(f,p,k)},lstroke:function(i){var f=parseInt(i[0]),p=y(parseInt(i[1])),k=y(parseInt(i[2]));u.setChannelMask(p,f),u.strokeLayer(p,k)},mouse:function(f){var p=parseInt(f[0]),k=parseInt(f[1]);u.showCursor(!0),u.moveCursor(p,k)},move:function(i){var f=parseInt(i[0]),p=parseInt(i[1]),k=parseInt(i[2]),A=parseInt(i[3]),L=parseInt(i[4]);if(f>0&&p>=0){var _=y(f),b=y(p);u.move(_,b,k,A,L)}},msg:function(i){var f,p,k=!0,A=parseInt(i[0]);if(e.onmsg&&(k=e.onmsg(A,i.slice(1)),k===void 0&&(k=!0)),k)switch(A){case n.Client.Message.USER_JOINED:f=i[1],p=i[2],e.onjoin&&e.onjoin(f,p);break;case n.Client.Message.USER_LEFT:f=i[1],p=i[2],e.onleave&&e.onleave(f,p);break}},name:function(i){e.onname&&e.onname(i[0])},nest:function(i){var f=T(parseInt(i[0]));f.receive(i[1])},pipe:function(i){var f=parseInt(i[0]),p=i[1],k=i[2];if(e.onpipe){var A=I[f]=new n.InputStream(e,f);e.onpipe(A,p,k)}else e.sendAck(f,"Named pipes unsupported",256)},png:function(i){var f=parseInt(i[0]),p=y(parseInt(i[1])),k=parseInt(i[2]),A=parseInt(i[3]),L=i[4];u.setChannelMask(p,f),u.draw(p,k,A,"data:image/png;base64,"+L)},pop:function(i){var f=y(parseInt(i[0]));u.pop(f)},push:function(i){var f=y(parseInt(i[0]));u.push(f)},rect:function(i){var f=y(parseInt(i[0])),p=parseInt(i[1]),k=parseInt(i[2]),A=parseInt(i[3]),L=parseInt(i[4]);u.rect(f,p,k,A,L)},required:function(f){e.onrequired&&e.onrequired(f)},reset:function(i){var f=y(parseInt(i[0]));u.reset(f)},set:function(i){var f=y(parseInt(i[0])),p=i[1],k=i[2],A=R[p];A&&A(f,k)},shade:function(i){var f=parseInt(i[0]),p=parseInt(i[1]);if(f>=0){var k=y(f);u.shade(k,p)}},size:function(i){var f=parseInt(i[0]),p=y(f),k=parseInt(i[1]),A=parseInt(i[2]);u.resize(p,k,A)},start:function(i){var f=y(parseInt(i[0])),p=parseInt(i[1]),k=parseInt(i[2]);u.moveTo(f,p,k)},sync:function(i){var f=parseInt(i[0]),p=i[1]?parseInt(i[1]):0;u.flush(function(){for(var A in S){var L=S[A];L&&L.sync()}f!==a&&(r.sendMessage("sync",f),a=f)},f,p),t===n.Client.State.WAITING&&v(n.Client.State.CONNECTED),e.onsync&&e.onsync(f,p)},transfer:function(i){var f=y(parseInt(i[0])),p=parseInt(i[1]),k=parseInt(i[2]),A=parseInt(i[3]),L=parseInt(i[4]),_=parseInt(i[5]),b=y(parseInt(i[6])),O=parseInt(i[7]),B=parseInt(i[8]);_===3?u.put(f,p,k,A,L,b,O,B):_!==5&&u.transfer(f,p,k,A,L,b,O,B,n.Client.DefaultTransferFunction[_])},transform:function(i){var f=y(parseInt(i[0])),p=parseFloat(i[1]),k=parseFloat(i[2]),A=parseFloat(i[3]),L=parseFloat(i[4]),_=parseFloat(i[5]),b=parseFloat(i[6]);u.transform(f,p,k,A,L,_,b)},undefine:function(f){var p=parseInt(f[0]),k=P[p];k&&k.onundefine&&k.onundefine()},video:function(i){var f=parseInt(i[0]),p=y(parseInt(i[1])),k=i[2],A=I[f]=new n.InputStream(e,f),L=null;e.onvideo&&(L=e.onvideo(A,p,k)),L||(L=n.VideoPlayer.getInstance(A,p,k)),L?(E[f]=L,e.sendAck(f,"OK",0)):e.sendAck(f,"BAD TYPE",783)}},D=function(){r.sendMessage("nop"),c=new Date().getTime()},F=function(){window.clearTimeout(o);var f=new Date().getTime(),p=Math.max(c+s-f,0);p>0?o=window.setTimeout(D,p):D()},H=function(){window.clearTimeout(o)};r.oninstruction=function(i,f){var p=M[i];p&&p(f),F()},this.disconnect=function(){t!=n.Client.State.DISCONNECTED&&t!=n.Client.State.DISCONNECTING&&(v(n.Client.State.DISCONNECTING),H(),r.sendMessage("disconnect"),r.disconnect(),v(n.Client.State.DISCONNECTED))},this.connect=function(i){v(n.Client.State.CONNECTING);try{r.connect(i)}catch(f){throw v(n.Client.State.IDLE),f}F(),v(n.Client.State.WAITING)}};n.Client.State={IDLE:0,CONNECTING:1,WAITING:2,CONNECTED:3,DISCONNECTING:4,DISCONNECTED:5};n.Client.DefaultTransferFunction={0:function(r,e){e.red=e.green=e.blue=0},15:function(r,e){e.red=e.green=e.blue=255},3:function(r,e){e.red=r.red,e.green=r.green,e.blue=r.blue,e.alpha=r.alpha},5:function(r,e){},12:function(r,e){e.red=255&~r.red,e.green=255&~r.green,e.blue=255&~r.blue,e.alpha=r.alpha},10:function(r,e){e.red=255&~e.red,e.green=255&~e.green,e.blue=255&~e.blue},1:function(r,e){e.red=r.red&e.red,e.green=r.green&e.green,e.blue=r.blue&e.blue},14:function(r,e){e.red=255&~(r.red&e.red),e.green=255&~(r.green&e.green),e.blue=255&~(r.blue&e.blue)},7:function(r,e){e.red=r.red|e.red,e.green=r.green|e.green,e.blue=r.blue|e.blue},8:function(r,e){e.red=255&~(r.red|e.red),e.green=255&~(r.green|e.green),e.blue=255&~(r.blue|e.blue)},6:function(r,e){e.red=r.red^e.red,e.green=r.green^e.green,e.blue=r.blue^e.blue},9:function(r,e){e.red=255&~(r.red^e.red),e.green=255&~(r.green^e.green),e.blue=255&~(r.blue^e.blue)},4:function(r,e){e.red=255&(~r.red&e.red),e.green=255&(~r.green&e.green),e.blue=255&(~r.blue&e.blue)},13:function(r,e){e.red=255&(~r.red|e.red),e.green=255&(~r.green|e.green),e.blue=255&(~r.blue|e.blue)},2:function(r,e){e.red=255&(r.red&~e.red),e.green=255&(r.green&~e.green),e.blue=255&(r.blue&~e.blue)},11:function(r,e){e.red=255&(r.red|~e.red),e.green=255&(r.green|~e.green),e.blue=255&(r.blue|~e.blue)}};n.Client.Message={USER_JOINED:1,USER_LEFT:2};var n=n||{};n.DataURIReader=function(r,e){var t=this,a="data:"+e+";base64,";r.onblob=function(o){a+=o},r.onend=function(){t.onend&&t.onend()},this.getURI=function(){return a},this.onend=null};var n=n||{};n.Display=function(){var r=this,e=0,t=0,a=1,s=document.createElement("div");s.style.position="relative",s.style.width=e+"px",s.style.height=t+"px",s.style.transformOrigin=s.style.webkitTransformOrigin=s.style.MozTransformOrigin=s.style.OTransformOrigin=s.style.msTransformOrigin="0 0";var o=new n.Display.VisibleLayer(e,t),c=new n.Display.VisibleLayer(0,0);c.setChannelMask(n.Layer.SRC),s.appendChild(o.getElement()),s.appendChild(c.getElement());var d=document.createElement("div");d.style.position="relative",d.style.width=e*a+"px",d.style.height=t*a+"px",d.appendChild(s),this.cursorHotspotX=0,this.cursorHotspotY=0,this.cursorX=0,this.cursorY=0,this.statisticWindow=0,this.onresize=null,this.oncursor=null,this.onstatistics=null;var m=[],u=[],h=function(){for(var v=0,x=0,y=0,w=0;w<u.length;){var T=u[w];if(!T.isReady())break;T.flush(),v=T.localTimestamp,x=T.remoteTimestamp,y+=T.logicalFrames,w++}u.splice(0,w),w&&E(v,x,y)},S=[],E=function(v,x,y){if(r.statisticWindow){for(var w=new Date().getTime(),T=0;T<S.length&&!(w-S[T].timestamp<=r.statisticWindow);T++);S.splice(0,T-1),S.push({localTimestamp:v,remoteTimestamp:x,timestamp:w,frames:y});var R=(S[S.length-1].timestamp-S[0].timestamp)/1e3,M=(S[S.length-1].remoteTimestamp-S[0].remoteTimestamp)/1e3,D=S.length,F=S.reduce(function(p,k){return p+k.frames},0),H=S.reduce(function(p,k){return p+Math.max(0,k.frames-1)},0),i=new n.Display.Statistics({processingLag:w-v,desktopFps:M&&F?F/M:null,clientFps:R?D/R:null,serverFps:M?D/M:null,dropRate:M?H/M:null});r.onstatistics&&r.onstatistics(i)}};function g(){h()}var I=function(v,x,y,w){this.localTimestamp=new Date().getTime(),this.remoteTimestamp=y||this.localTimestamp,this.logicalFrames=w||0,this.cancel=function(){v=null,x.forEach(function(M){M.cancel()}),x=[]},this.isReady=function(){for(var T=0;T<x.length;T++)if(x[T].blocked)return!1;return!0},this.flush=function(){for(var T=0;T<x.length;T++)x[T].execute();v&&v()}};function P(l,v){var x=this;this.blocked=v,this.cancel=function(){x.blocked=!1,l=null},this.unblock=function(){x.blocked&&(x.blocked=!1,u.length&&g())},this.execute=function(){l&&l()}}function C(l,v){var x=new P(l,v);return m.push(x),x}this.getElement=function(){return d},this.getWidth=function(){return e},this.getHeight=function(){return t},this.getDefaultLayer=function(){return o},this.getCursorLayer=function(){return c},this.createLayer=function(){var l=new n.Display.VisibleLayer(e,t);return l.move(o,0,0,0),l},this.createBuffer=function(){var l=new n.Layer(0,0);return l.autosize=1,l},this.flush=function(l,v,x){u.push(new I(l,m,v,x)),m=[],g()},this.cancel=function(){u.forEach(function(x){x.cancel()}),u=[],m.forEach(function(x){x.cancel()}),m=[]},this.setCursor=function(l,v,x,y,w,T,R){C(function(){r.cursorHotspotX=l,r.cursorHotspotY=v,c.resize(T,R),c.copy(x,y,w,T,R,0,0),r.moveCursor(r.cursorX,r.cursorY),r.oncursor&&r.oncursor(c.toCanvas(),l,v)})},this.showCursor=function(l){var v=c.getElement(),x=v.parentNode;l===!1?x&&x.removeChild(v):x!==s&&s.appendChild(v)},this.moveCursor=function(l,v){c.translate(l-r.cursorHotspotX,v-r.cursorHotspotY),r.cursorX=l,r.cursorY=v},this.resize=function(l,v,x){C(function(){l.resize(v,x),l===o&&(e=v,t=x,s.style.width=e+"px",s.style.height=t+"px",d.style.width=e*a+"px",d.style.height=t*a+"px",r.onresize&&r.onresize(v,x))})},this.drawImage=function(l,v,x,y){C(function(){l.drawImage(v,x,y)})},this.drawBlob=function(l,v,x,y){var w;if(window.createImageBitmap){var T;w=C(function(){l.drawImage(v,x,T)},!0),window.createImageBitmap(y).then(function(F){T=F,w.unblock()})}else{var R=URL.createObjectURL(y);w=C(function(){M.width&&M.height&&l.drawImage(v,x,M),URL.revokeObjectURL(R)},!0);var M=new Image;M.onload=w.unblock,M.onerror=w.unblock,M.src=R}},this.drawStream=function(v,x,y,w,T){if(window.ImageDecoder&&window.ReadableStream){var R=new ImageDecoder({type:T,data:w.toReadableStream()}),M=null,D=C(function(){v.drawImage(x,y,M)},!0);R.decode({completeFramesOnly:!0}).then(function(i){M=i.image,D.unblock()})}else{var F=new n.DataURIReader(w,T);F.onend=function(){r.draw(v,x,y,F.getURI())}}},this.draw=function(l,v,x,y){var w=C(function(){T.width&&T.height&&l.drawImage(v,x,T)},!0),T=new Image;T.onload=w.unblock,T.onerror=w.unblock,T.src=y},this.play=function(l,v,x,y){var w=document.createElement("video");w.type=v,w.src=y,w.addEventListener("play",function(){function T(){l.drawImage(0,0,w),w.ended||window.setTimeout(T,20)}T()},!1),C(w.play)},this.transfer=function(l,v,x,y,w,T,R,M,D){C(function(){T.transfer(l,v,x,y,w,R,M,D)})},this.put=function(l,v,x,y,w,T,R,M){C(function(){T.put(l,v,x,y,w,R,M)})},this.copy=function(l,v,x,y,w,T,R,M){C(function(){T.copy(l,v,x,y,w,R,M)})},this.moveTo=function(l,v,x){C(function(){l.moveTo(v,x)})},this.lineTo=function(l,v,x){C(function(){l.lineTo(v,x)})},this.arc=function(l,v,x,y,w,T,R){C(function(){l.arc(v,x,y,w,T,R)})},this.curveTo=function(l,v,x,y,w,T,R){C(function(){l.curveTo(v,x,y,w,T,R)})},this.close=function(l){C(function(){l.close()})},this.rect=function(l,v,x,y,w){C(function(){l.rect(v,x,y,w)})},this.clip=function(l){C(function(){l.clip()})},this.strokeColor=function(l,v,x,y,w,T,R,M){C(function(){l.strokeColor(v,x,y,w,T,R,M)})},this.fillColor=function(l,v,x,y,w){C(function(){l.fillColor(v,x,y,w)})},this.strokeLayer=function(l,v,x,y,w){C(function(){l.strokeLayer(v,x,y,w)})},this.fillLayer=function(l,v){C(function(){l.fillLayer(v)})},this.push=function(l){C(function(){l.push()})},this.pop=function(l){C(function(){l.pop()})},this.reset=function(l){C(function(){l.reset()})},this.setTransform=function(l,v,x,y,w,T,R){C(function(){l.setTransform(v,x,y,w,T,R)})},this.transform=function(l,v,x,y,w,T,R){C(function(){l.transform(v,x,y,w,T,R)})},this.setChannelMask=function(l,v){C(function(){l.setChannelMask(v)})},this.setMiterLimit=function(l,v){C(function(){l.setMiterLimit(v)})},this.dispose=function(v){C(function(){v.dispose()})},this.distort=function(v,x,y,w,T,R,M){C(function(){v.distort(x,y,w,T,R,M)})},this.move=function(v,x,y,w,T){C(function(){v.move(x,y,w,T)})},this.shade=function(v,x){C(function(){v.shade(x)})},this.scale=function(l){s.style.transform=s.style.WebkitTransform=s.style.MozTransform=s.style.OTransform=s.style.msTransform="scale("+l+","+l+")",a=l,d.style.width=e*a+"px",d.style.height=t*a+"px"},this.getScale=function(){return a},this.flatten=function(){var l=document.createElement("canvas");l.width=o.width,l.height=o.height;var v=l.getContext("2d");function x(w){var T=[];for(var R in w.children)T.push(w.children[R]);return T.sort(function(D,F){var H=D.z-F.z;if(H!==0)return H;var i=D.getElement(),f=F.getElement(),p=f.compareDocumentPosition(i);return p&Node.DOCUMENT_POSITION_PRECEDING?-1:p&Node.DOCUMENT_POSITION_FOLLOWING?1:0}),T}function y(w,T,R){if(w.width>0&&w.height>0){var M=v.globalAlpha;v.globalAlpha*=w.alpha/255,v.drawImage(w.getCanvas(),T,R);for(var D=x(w),F=0;F<D.length;F++){var H=D[F];y(H,T+H.x,R+H.y)}v.globalAlpha=M}}return y(o,0,0),l}};n.Display.VisibleLayer=function(r,e){n.Layer.apply(this,[r,e]);var t=this;this.__unique_id=n.Display.VisibleLayer.__next_id++,this.alpha=255,this.x=0,this.y=0,this.z=0,this.matrix=[1,0,0,1,0,0],this.parent=null,this.children={};var a=t.getCanvas();a.style.position="absolute",a.style.left="0px",a.style.top="0px";var s=document.createElement("div");s.appendChild(a),s.style.width=r+"px",s.style.height=e+"px",s.style.position="absolute",s.style.left="0px",s.style.top="0px",s.style.overflow="hidden";var o=this.resize;this.resize=function(m,u){s.style.width=m+"px",s.style.height=u+"px",o(m,u)},this.getElement=function(){return s};var c="translate(0px, 0px)",d="matrix(1, 0, 0, 1, 0, 0)";this.translate=function(m,u){t.x=m,t.y=u,c="translate("+m+"px,"+u+"px)",s.style.transform=s.style.WebkitTransform=s.style.MozTransform=s.style.OTransform=s.style.msTransform=c+" "+d},this.move=function(m,u,h,S){if(t.parent!==m){t.parent&&delete t.parent.children[t.__unique_id],t.parent=m,m.children[t.__unique_id]=t;var E=m.getElement();E.appendChild(s)}t.translate(u,h),t.z=S,s.style.zIndex=S},this.shade=function(m){t.alpha=m,s.style.opacity=m/255},this.dispose=function(){t.parent&&(delete t.parent.children[t.__unique_id],t.parent=null),s.parentNode&&s.parentNode.removeChild(s)},this.distort=function(m,u,h,S,E,g){t.matrix=[m,u,h,S,E,g],d="matrix("+m+","+u+","+h+","+S+","+E+","+g+")",s.style.transform=s.style.WebkitTransform=s.style.MozTransform=s.style.OTransform=s.style.msTransform=c+" "+d}};n.Display.VisibleLayer.__next_id=0;n.Display.Statistics=function(e){e=e||{},this.processingLag=e.processingLag,this.desktopFps=e.desktopFps,this.serverFps=e.serverFps,this.clientFps=e.clientFps,this.dropRate=e.dropRate};var n=n||{};n.Event=function(e){this.type=e,this.timestamp=new Date().getTime(),this.getAge=function(){return new Date().getTime()-this.timestamp},this.invokeLegacyHandler=function(a){}};n.Event.DOMEvent=function(e,t){n.Event.call(this,e),t=t||[],Array.isArray(t)||(t=[t]),this.preventDefault=function(){t.forEach(function(o){o.preventDefault&&o.preventDefault(),o.returnValue=!1})},this.stopPropagation=function(){t.forEach(function(o){o.stopPropagation()})}};n.Event.DOMEvent.cancelEvent=function(e){e.stopPropagation(),e.preventDefault&&e.preventDefault(),e.returnValue=!1};n.Event.Target=function(){var e={};this.on=function(a,s){var o=e[a];o||(e[a]=o=[]),o.push(s)},this.onEach=function(a,s){a.forEach(function(c){this.on(c,s)},this)},this.dispatch=function(a){a.invokeLegacyHandler(this);var s=e[a.type];if(s)for(var o=0;o<s.length;o++)s[o](a,this)},this.off=function(a,s){var o=e[a];if(!o)return!1;for(var c=0;c<o.length;c++)if(o[c]===s)return o.splice(c,1),!0;return!1},this.offEach=function(a,s){var o=!1;return a.forEach(function(d){o|=this.off(d,s)},this),o}};var n=n||{};n.InputSink=function(){var e=this,t=document.createElement("textarea");t.style.position="fixed",t.style.outline="none",t.style.border="none",t.style.margin="0",t.style.padding="0",t.style.height="0",t.style.width="0",t.style.left="0",t.style.bottom="0",t.style.resize="none",t.style.background="transparent",t.style.color="transparent",t.addEventListener("keypress",function(s){t.value=""},!1),t.addEventListener("compositionend",function(s){s.data&&(t.value="")},!1),t.addEventListener("input",function(s){s.data&&!s.isComposing&&(t.value="")},!1),t.addEventListener("focus",function(){window.setTimeout(function(){t.click(),t.select()},0)},!0),this.focus=function(){window.setTimeout(function(){t.focus()},0)},this.getElement=function(){return t},document.addEventListener("keydown",function(s){var o=document.activeElement;if(o&&o!==document.body){var c=o.getBoundingClientRect();if(c.left+c.width>0&&c.top+c.height>0)return}e.focus()},!0)};var n=n||{};n.InputStream=function(r,e){var t=this;this.index=e,this.onblob=null,this.onend=null,this.sendAck=function(a,s){r.sendAck(t.index,a,s)},this.toReadableStream=function(){return new ReadableStream({type:"bytes",start:function(o){var c=new n.ArrayBufferReader(t);c.ondata=function(m){if(o.byobRequest){var u=o.byobRequest.view,h=Math.min(u.byteLength,m.byteLength),S=new Uint8Array(m,0,h);u.buffer.set(S),o.byobRequest.respond(h),h<m.byteLength&&o.enqueue(m.slice(h))}else o.enqueue(new Uint8Array(m))},c.onend=function(){o.close()}}})}};var n=n||{};n.IntegerPool=function(){var r=this,e=[];this.next_int=0,this.next=function(){return e.length>0?e.shift():r.next_int++},this.free=function(t){e.push(t)}};var n=n||{};n.JSONReader=function(e){var t=this,a=new n.StringReader(e),s="";this.getLength=function(){return s.length},this.getJSON=function(){return JSON.parse(s)},a.ontext=function(c){s+=c,t.onprogress&&t.onprogress(c.length)},a.onend=function(){t.onend&&t.onend()},this.onprogress=null,this.onend=null};var n=n||{};n.Keyboard=function(e){var t=this,a=n.Keyboard._nextID++,s="_GUAC_KEYBOARD_HANDLED_BY_"+a;this.onkeydown=null,this.onkeyup=null;var o={keyupUnreliable:!1,altIsTypableOnly:!1,capsLockKeyEventUnreliable:!1};navigator&&navigator.platform&&(navigator.platform.match(/ipad|iphone|ipod/i)?o.keyupUnreliable=!0:navigator.platform.match(/^mac/i)&&(o.altIsTypableOnly=!0,o.capsLockKeyEventUnreliable=!0));var c=function(b){var O=this;this.keyCode=b?b.which||b.keyCode:0,this.keyIdentifier=b&&b.keyIdentifier,this.key=b&&b.key,this.location=b?A(b):0,this.modifiers=b?n.Keyboard.ModifierState.fromKeyboardEvent(b):new n.Keyboard.ModifierState,this.timestamp=new Date().getTime(),this.defaultPrevented=!1,this.keysym=null,this.reliable=!1,this.getAge=function(){return new Date().getTime()-O.timestamp}},d=function(b){c.call(this,b),this.keysym=w(this.key,this.location)||M(this.keyCode,this.location),this.keyupReliable=!o.keyupUnreliable,this.keysym&&!y(this.keysym)&&(this.reliable=!0),!this.keysym&&D(this.keyCode,this.keyIdentifier)&&(this.keysym=w(this.keyIdentifier,this.location,this.modifiers.shift)),this.modifiers.meta&&this.keysym!==65511&&this.keysym!==65512?this.keyupReliable=!1:this.keysym===65509&&o.capsLockKeyEventUnreliable&&(this.keyupReliable=!1);var O=!this.modifiers.ctrl&&!o.altIsTypableOnly;o.altIsTypableOnly&&(this.keysym===65513||this.keysym===65514)&&(this.keysym=65027);var B=!this.modifiers.alt;(B&&this.modifiers.ctrl||O&&this.modifiers.alt||this.modifiers.meta||this.modifiers.hyper)&&(this.reliable=!0),C[this.keyCode]=this.keysym};d.prototype=new c;var m=function(b){c.call(this,b),this.keysym=R(this.keyCode),this.reliable=!0};m.prototype=new c;var u=function(b){if(c.call(this,b),this.keyCode==20&&o.capsLockKeyEventUnreliable){h.push(new d(this));return}this.keysym=M(this.keyCode,this.location)||w(this.key,this.location),t.pressed[this.keysym]||(this.keysym=C[this.keyCode]||this.keysym),this.reliable=!0};u.prototype=new c;var h=[],S={8:[65288],9:[65289],12:[65291,65291,65291,65461],13:[65293],16:[65505,65505,65506],17:[65507,65507,65508],18:[65513,65513,65514],19:[65299],20:[65509],27:[65307],32:[32],33:[65365,65365,65365,65465],34:[65366,65366,65366,65459],35:[65367,65367,65367,65457],36:[65360,65360,65360,65463],37:[65361,65361,65361,65460],38:[65362,65362,65362,65464],39:[65363,65363,65363,65462],40:[65364,65364,65364,65458],45:[65379,65379,65379,65456],46:[65535,65535,65535,65454],91:[65511],92:[65512],93:[65383],96:[65456],97:[65457],98:[65458],99:[65459],100:[65460],101:[65461],102:[65462],103:[65463],104:[65464],105:[65465],106:[65450],107:[65451],109:[65453],110:[65454],111:[65455],112:[65470],113:[65471],114:[65472],115:[65473],116:[65474],117:[65475],118:[65476],119:[65477],120:[65478],121:[65479],122:[65480],123:[65481],144:[65407],145:[65300],225:[65027]},E={Again:[65382],AllCandidates:[65341],Alphanumeric:[65328],Alt:[65513,65513,65514],Attn:[64782],AltGraph:[65027],ArrowDown:[65364],ArrowLeft:[65361],ArrowRight:[65363],ArrowUp:[65362],Backspace:[65288],CapsLock:[65509],Cancel:[65385],Clear:[65291],Convert:[65315],Copy:[64789],Crsel:[64796],CrSel:[64796],CodeInput:[65335],Compose:[65312],Control:[65507,65507,65508],ContextMenu:[65383],Delete:[65535],Down:[65364],End:[65367],Enter:[65293],EraseEof:[64774],Escape:[65307],Execute:[65378],Exsel:[64797],ExSel:[64797],F1:[65470],F2:[65471],F3:[65472],F4:[65473],F5:[65474],F6:[65475],F7:[65476],F8:[65477],F9:[65478],F10:[65479],F11:[65480],F12:[65481],F13:[65482],F14:[65483],F15:[65484],F16:[65485],F17:[65486],F18:[65487],F19:[65488],F20:[65489],F21:[65490],F22:[65491],F23:[65492],F24:[65493],Find:[65384],GroupFirst:[65036],GroupLast:[65038],GroupNext:[65032],GroupPrevious:[65034],FullWidth:null,HalfWidth:null,HangulMode:[65329],Hankaku:[65321],HanjaMode:[65332],Help:[65386],Hiragana:[65317],HiraganaKatakana:[65319],Home:[65360],Hyper:[65517,65517,65518],Insert:[65379],JapaneseHiragana:[65317],JapaneseKatakana:[65318],JapaneseRomaji:[65316],JunjaMode:[65336],KanaMode:[65325],KanjiMode:[65313],Katakana:[65318],Left:[65361],Meta:[65511,65511,65512],ModeChange:[65406],NonConvert:[65314],NumLock:[65407],PageDown:[65366],PageUp:[65365],Pause:[65299],Play:[64790],PreviousCandidate:[65342],PrintScreen:[65377],Redo:[65382],Right:[65363],Romaji:[65316],RomanCharacters:null,Scroll:[65300],Select:[65376],Separator:[65452],Shift:[65505,65505,65506],SingleCandidate:[65340],Super:[65515,65515,65516],Tab:[65289],UIKeyInputDownArrow:[65364],UIKeyInputEscape:[65307],UIKeyInputLeftArrow:[65361],UIKeyInputRightArrow:[65363],UIKeyInputUpArrow:[65362],Up:[65362],Undo:[65381],Win:[65511,65511,65512],Zenkaku:[65320],ZenkakuHankaku:[65322]},g={65027:!0,65505:!0,65506:!0,65507:!0,65508:!0,65509:!0,65511:!0,65512:!0,65513:!0,65514:!0,65515:!0,65516:!0};this.modifiers=new n.Keyboard.ModifierState,this.pressed={};var I={},P={},C={},l=null,v=null,x=function(b,O){return b?b[O]||b[0]:null},y=function(b){return b>=0&&b<=255||(b&4294901760)===16777216};function w(_,b,O){if(!_)return null;var B,Y=_.indexOf("U+");if(Y>=0){var U=_.substring(Y+2);B=String.fromCharCode(parseInt(U,16))}else if(_.length===1&&b!==3)B=_;else return x(E[_],b);O===!0?B=B.toUpperCase():O===!1&&(B=B.toLowerCase());var N=B.charCodeAt(0);return R(N)}function T(_){return _<=31||_>=127&&_<=159}function R(_){return T(_)?65280|_:_>=0&&_<=255?_:_>=256&&_<=1114111?16777216|_:null}function M(_,b){return x(S[_],b)}var D=function(b,O){if(!O)return!1;var B=O.indexOf("U+");if(B===-1)return!0;var Y=parseInt(O.substring(B+2),16);return b!==Y||b>=65&&b<=90||b>=48&&b<=57};this.press=function(_){if(_!==null){if(!t.pressed[_]&&(t.pressed[_]=!0,t.onkeydown)){var b=t.onkeydown(_);return P[_]=b,window.clearTimeout(l),window.clearInterval(v),g[_]||(l=window.setTimeout(function(){v=window.setInterval(function(){t.onkeyup(_),t.onkeydown(_)},50)},500)),b}return P[_]||!1}},this.release=function(_){t.pressed[_]&&(delete t.pressed[_],delete I[_],window.clearTimeout(l),window.clearInterval(v),_!==null&&t.onkeyup&&t.onkeyup(_))},this.type=function(b){for(var O=0;O<b.length;O++){var B=b.codePointAt?b.codePointAt(O):b.charCodeAt(O),Y=R(B);t.press(Y),t.release(Y)}},this.reset=function(){for(var _ in t.pressed)t.release(parseInt(_));h=[]};var F=function(b,O,B){var Y=B.modifiers[b],U=t.modifiers[b],N;if(O.indexOf(B.keysym)===-1){if(U&&Y===!1)for(N=0;N<O.length;N++)t.release(O[N]);else if(!U&&Y){for(N=0;N<O.length;N++)if(t.pressed[O[N]])return;var V=O[0];B.keysym&&(I[V]=!0),t.press(V)}}},H=function(b){F("alt",[65513,65514,65027],b),F("shift",[65505,65506],b),F("ctrl",[65507,65508],b),F("meta",[65511,65512],b),F("hyper",[65515,65516],b),t.modifiers=b.modifiers},i=function(){for(var b in t.pressed)if(!I[b])return!1;return!0};function f(){var _=k();if(!_)return!1;var b;do b=_,_=k();while(_!==null);return i()&&t.reset(),b.defaultPrevented}var p=function(b){!t.modifiers.ctrl||!t.modifiers.alt||b>=65&&b<=90||b>=97&&b<=122||(b<=255||(b&4278190080)===16777216)&&(t.release(65507),t.release(65508),t.release(65513),t.release(65514))},k=function(){var b=h[0];if(!b)return null;if(b instanceof d){var O=null,B=[];if(b.keysym===65511||b.keysym===65512){if(h.length===1)return null;if(h[1].keysym!==b.keysym){if(!h[1].modifiers.meta)return h.shift()}else if(h[1]instanceof d)return h.shift()}if(b.reliable?(O=b.keysym,B=h.splice(0,1)):h[1]instanceof m?(O=h[1].keysym,B=h.splice(0,2)):h[1]&&(O=b.keysym,B=h.splice(0,1)),B.length>0){if(H(b),O){p(O);var Y=!t.press(O);C[b.keyCode]=O,b.keyupReliable||t.release(O);for(var U=0;U<B.length;U++)B[U].defaultPrevented=Y}return b}}else if(b instanceof u&&!o.keyupUnreliable){var O=b.keysym;if(O)t.release(O),delete C[b.keyCode],b.defaultPrevented=!0;else return t.reset(),b;return H(b),h.shift()}else return h.shift();return null},A=function(b){return"location"in b?b.location:"keyLocation"in b?b.keyLocation:0},L=function(b){return b[s]?!1:(b[s]=!0,!0)};this.listenTo=function(b){b.addEventListener("keydown",function(U){if(t.onkeydown&&L(U)){var N=new d(U);U.isComposing||N.keyCode===229||(h.push(N),f()&&U.preventDefault())}},!0),b.addEventListener("keypress",function(U){!t.onkeydown&&!t.onkeyup||L(U)&&(h.push(new m(U)),f()&&U.preventDefault())},!0),b.addEventListener("keyup",function(U){t.onkeyup&&L(U)&&(U.preventDefault(),h.push(new u(U)),f())},!0);var O=function(N){!t.onkeydown&&!t.onkeyup||L(N)&&N.data&&!N.isComposing&&t.type(N.data)},B=function(N){b.removeEventListener("input",O,!1)},Y=function(N){!t.onkeydown&&!t.onkeyup||L(N)&&N.data&&t.type(N.data)};b.addEventListener("input",O,!1),b.addEventListener("compositionend",Y,!1),b.addEventListener("compositionstart",B,!1)},e&&t.listenTo(e)};n.Keyboard._nextID=0;n.Keyboard.ModifierState=function(){this.shift=!1,this.ctrl=!1,this.alt=!1,this.meta=!1,this.hyper=!1};n.Keyboard.ModifierState.fromKeyboardEvent=function(r){var e=new n.Keyboard.ModifierState;return e.shift=r.shiftKey,e.ctrl=r.ctrlKey,e.alt=r.altKey,e.meta=r.metaKey,r.getModifierState&&(e.hyper=r.getModifierState("OS")||r.getModifierState("Super")||r.getModifierState("Hyper")||r.getModifierState("Win")),e};var n=n||{};n.KeyEventInterpreter=function(e){e==null&&(e=0);var t=[{keysym:65027,name:"AltGr"},{keysym:65288,name:"Backspace"},{keysym:65289,name:"Tab"},{keysym:65291,name:"Clear"},{keysym:65293,name:"Return",value:`\n`},{keysym:65299,name:"Pause"},{keysym:65300,name:"Scroll"},{keysym:65301,name:"SysReq"},{keysym:65307,name:"Escape"},{keysym:65360,name:"Home"},{keysym:65361,name:"Left"},{keysym:65362,name:"Up"},{keysym:65363,name:"Right"},{keysym:65364,name:"Down"},{keysym:65365,name:"Page Up"},{keysym:65366,name:"Page Down"},{keysym:65367,name:"End"},{keysym:65379,name:"Insert"},{keysym:65381,name:"Undo"},{keysym:65386,name:"Help"},{keysym:65407,name:"Num"},{keysym:65408,name:"Space",value:" "},{keysym:65421,name:"Enter",value:`\n`},{keysym:65429,name:"Home"},{keysym:65430,name:"Left"},{keysym:65431,name:"Up"},{keysym:65432,name:"Right"},{keysym:65433,name:"Down"},{keysym:65434,name:"Page Up"},{keysym:65435,name:"Page Down"},{keysym:65436,name:"End"},{keysym:65438,name:"Insert"},{keysym:65450,name:"*",value:"*"},{keysym:65451,name:"+",value:"+"},{keysym:65453,name:"-",value:"-"},{keysym:65454,name:".",value:"."},{keysym:65455,name:"/",value:"/"},{keysym:65456,name:"0",value:"0"},{keysym:65457,name:"1",value:"1"},{keysym:65458,name:"2",value:"2"},{keysym:65459,name:"3",value:"3"},{keysym:65460,name:"4",value:"4"},{keysym:65461,name:"5",value:"5"},{keysym:65462,name:"6",value:"6"},{keysym:65463,name:"7",value:"7"},{keysym:65464,name:"8",value:"8"},{keysym:65465,name:"9",value:"9"},{keysym:65470,name:"F1"},{keysym:65471,name:"F2"},{keysym:65472,name:"F3"},{keysym:65473,name:"F4"},{keysym:65474,name:"F5"},{keysym:65475,name:"F6"},{keysym:65476,name:"F7"},{keysym:65477,name:"F8"},{keysym:65478,name:"F9"},{keysym:65479,name:"F10"},{keysym:65480,name:"F11"},{keysym:65481,name:"F12"},{keysym:65482,name:"F13"},{keysym:65483,name:"F14"},{keysym:65484,name:"F15"},{keysym:65485,name:"F16"},{keysym:65486,name:"F17"},{keysym:65487,name:"F18"},{keysym:65488,name:"F19"},{keysym:65489,name:"F20"},{keysym:65490,name:"F21"},{keysym:65491,name:"F22"},{keysym:65492,name:"F23"},{keysym:65493,name:"F24"},{keysym:65505,name:"Shift"},{keysym:65506,name:"Shift"},{keysym:65507,name:"Ctrl"},{keysym:65508,name:"Ctrl"},{keysym:65509,name:"Caps"},{keysym:65511,name:"Meta"},{keysym:65512,name:"Meta"},{keysym:65513,name:"Alt"},{keysym:65514,name:"Alt"},{keysym:65515,name:"Super"},{keysym:65516,name:"Super"},{keysym:65517,name:"Hyper"},{keysym:65518,name:"Hyper"},{keysym:65535,name:"Delete"}],a={};t.forEach(function(m){a[m.keysym]=new n.KeyEventInterpreter.KeyDefinition(m)});var s=[];function o(d){if(d<0||d>255&&(d|65535)!=16842751)return null;var m=d&65535,u=String.fromCharCode(m);return new n.KeyEventInterpreter.KeyDefinition({keysym:d,name:u,value:u})}function c(d){if(d in a)return a[d];var m=o(d);return m??new n.KeyEventInterpreter.KeyDefinition({keysym:d,name:"0x"+String(d.toString(16))})}this.handleKeyEvent=function(m){var u=parseInt(m[0]),h=parseInt(m[1]),S=parseInt(m[2]),E=S-e,g=c(u);s.push(new n.KeyEventInterpreter.KeyEvent({definition:g,pressed:h,timestamp:E}))},this.getEvents=function(){return s}};n.KeyEventInterpreter.KeyDefinition=function(e){e=e||{},this.keysym=parseInt(e.keysym),this.name=e.name,this.value=e.value};n.KeyEventInterpreter.KeyEvent=function(e){e=e||{},this.definition=e.definition,this.pressed=!!e.pressed,this.timestamp=e.timestamp};var n=n||{};n.Layer=function(r,e){var t=this,a=64,s=document.createElement("canvas"),o=s.getContext("2d");o.save();var c=!0,d=!0,m=0,u={1:"destination-in",2:"destination-out",4:"source-in",6:"source-atop",8:"source-out",9:"destination-atop",10:"xor",11:"destination-over",12:"copy",14:"source-over",15:"lighter"},h=function(g,I){g=g||0,I=I||0;var P=Math.ceil(g/a)*a,C=Math.ceil(I/a)*a;if(s.width!==P||s.height!==C){var l=null;if(!c&&s.width!==0&&s.height!==0){l=document.createElement("canvas"),l.width=Math.min(t.width,g),l.height=Math.min(t.height,I);var v=l.getContext("2d");v.drawImage(s,0,0,l.width,l.height,0,0,l.width,l.height)}var x=o.globalCompositeOperation;s.width=P,s.height=C,l&&o.drawImage(l,0,0,l.width,l.height,0,0,l.width,l.height),o.globalCompositeOperation=x,m=0,o.save()}else t.reset();t.width=g,t.height=I};function S(E,g,I,P){var C=I+E,l=P+g,v;C>t.width?v=C:v=t.width;var x;l>t.height?x=l:x=t.height,t.resize(v,x)}this.autosize=!1,this.width=r,this.height=e,this.getCanvas=function(){return s},this.toCanvas=function(){var g=document.createElement("canvas");g.width=t.width,g.height=t.height;var I=g.getContext("2d");return I.drawImage(t.getCanvas(),0,0),g},this.resize=function(E,g){(E!==t.width||g!==t.height)&&h(E,g)},this.drawImage=function(E,g,I){t.autosize&&S(E,g,I.width,I.height),o.drawImage(I,E,g),c=!1},this.transfer=function(E,g,I,P,C,l,v,x){var y=E.getCanvas();if(!(g>=y.width||I>=y.height)&&(g+P>y.width&&(P=y.width-g),I+C>y.height&&(C=y.height-I),!(P===0||C===0))){t.autosize&&S(l,v,P,C);for(var w=E.getCanvas().getContext("2d").getImageData(g,I,P,C),T=o.getImageData(l,v,P,C),R=0;R<P*C*4;R+=4){var M=new n.Layer.Pixel(w.data[R],w.data[R+1],w.data[R+2],w.data[R+3]),D=new n.Layer.Pixel(T.data[R],T.data[R+1],T.data[R+2],T.data[R+3]);x(M,D),T.data[R]=D.red,T.data[R+1]=D.green,T.data[R+2]=D.blue,T.data[R+3]=D.alpha}o.putImageData(T,l,v),c=!1}},this.put=function(E,g,I,P,C,l,v){var x=E.getCanvas();if(!(g>=x.width||I>=x.height)&&(g+P>x.width&&(P=x.width-g),I+C>x.height&&(C=x.height-I),!(P===0||C===0))){t.autosize&&S(l,v,P,C);var y=E.getCanvas().getContext("2d").getImageData(g,I,P,C);o.putImageData(y,l,v),c=!1}},this.copy=function(E,g,I,P,C,l,v){var x=E.getCanvas();g>=x.width||I>=x.height||(g+P>x.width&&(P=x.width-g),I+C>x.height&&(C=x.height-I),!(P===0||C===0)&&(t.autosize&&S(l,v,P,C),o.drawImage(x,g,I,P,C,l,v,P,C),c=!1))},this.moveTo=function(E,g){d&&(o.beginPath(),d=!1),t.autosize&&S(E,g,0,0),o.moveTo(E,g)},this.lineTo=function(E,g){d&&(o.beginPath(),d=!1),t.autosize&&S(E,g,0,0),o.lineTo(E,g)},this.arc=function(E,g,I,P,C,l){d&&(o.beginPath(),d=!1),t.autosize&&S(E,g,0,0),o.arc(E,g,I,P,C,l)},this.curveTo=function(E,g,I,P,C,l){d&&(o.beginPath(),d=!1),t.autosize&&S(C,l,0,0),o.bezierCurveTo(E,g,I,P,C,l)},this.close=function(){o.closePath(),d=!0},this.rect=function(E,g,I,P){d&&(o.beginPath(),d=!1),t.autosize&&S(E,g,I,P),o.rect(E,g,I,P)},this.clip=function(){o.clip(),d=!0},this.strokeColor=function(E,g,I,P,C,l,v){o.lineCap=E,o.lineJoin=g,o.lineWidth=I,o.strokeStyle="rgba("+P+","+C+","+l+","+v/255+")",o.stroke(),c=!1,d=!0},this.fillColor=function(E,g,I,P){o.fillStyle="rgba("+E+","+g+","+I+","+P/255+")",o.fill(),c=!1,d=!0},this.strokeLayer=function(E,g,I,P){o.lineCap=E,o.lineJoin=g,o.lineWidth=I,o.strokeStyle=o.createPattern(P.getCanvas(),"repeat"),o.stroke(),c=!1,d=!0},this.fillLayer=function(E){o.fillStyle=o.createPattern(E.getCanvas(),"repeat"),o.fill(),c=!1,d=!0},this.push=function(){o.save(),m++},this.pop=function(){m>0&&(o.restore(),m--)},this.reset=function(){for(;m>0;)o.restore(),m--;o.restore(),o.save(),o.beginPath(),d=!1},this.setTransform=function(E,g,I,P,C,l){o.setTransform(E,g,I,P,C,l)},this.transform=function(E,g,I,P,C,l){o.transform(E,g,I,P,C,l)},this.setChannelMask=function(E){o.globalCompositeOperation=u[E]},this.setMiterLimit=function(E){o.miterLimit=E},h(r,e),s.style.zIndex=-1};n.Layer.ROUT=2;n.Layer.ATOP=6;n.Layer.XOR=10;n.Layer.ROVER=11;n.Layer.OVER=14;n.Layer.PLUS=15;n.Layer.RIN=1;n.Layer.IN=4;n.Layer.OUT=8;n.Layer.RATOP=9;n.Layer.SRC=12;n.Layer.Pixel=function(r,e,t,a){this.red=r,this.green=e,this.blue=t,this.alpha=a};var n=n||{};n.Mouse=function(e){n.Mouse.Event.Target.call(this);var t=this;this.touchMouseThreshold=3,this.scrollThreshold=53,this.PIXELS_PER_LINE=18,this.PIXELS_PER_PAGE=this.PIXELS_PER_LINE*16;var a=[n.Mouse.State.Buttons.LEFT,n.Mouse.State.Buttons.MIDDLE,n.Mouse.State.Buttons.RIGHT],s=0,o=0;e.addEventListener("contextmenu",function(u){n.Event.DOMEvent.cancelEvent(u)},!1),e.addEventListener("mousemove",function(u){if(s){n.Event.DOMEvent.cancelEvent(u),s--;return}t.move(n.Position.fromClientPosition(e,u.clientX,u.clientY),u)},!1),e.addEventListener("mousedown",function(u){if(s){n.Event.DOMEvent.cancelEvent(u);return}var h=a[u.button];h&&t.press(h,u)},!1),e.addEventListener("mouseup",function(u){if(s){n.Event.DOMEvent.cancelEvent(u);return}var h=a[u.button];h&&t.release(h,u)},!1),e.addEventListener("mouseout",function(u){u||(u=window.event);for(var h=u.relatedTarget||u.toElement;h;){if(h===e)return;h=h.parentNode}t.reset(u),t.out(u)},!1),e.addEventListener("selectstart",function(u){n.Event.DOMEvent.cancelEvent(u)},!1);function c(){s=t.touchMouseThreshold}e.addEventListener("touchmove",c,!1),e.addEventListener("touchstart",c,!1),e.addEventListener("touchend",c,!1);function d(u){var h=u.deltaY||-u.wheelDeltaY||-u.wheelDelta;if(h?u.deltaMode===1?h=u.deltaY*t.PIXELS_PER_LINE:u.deltaMode===2&&(h=u.deltaY*t.PIXELS_PER_PAGE):h=u.detail*t.PIXELS_PER_LINE,o+=h,o<=-t.scrollThreshold){do t.click(n.Mouse.State.Buttons.UP),o+=t.scrollThreshold;while(o<=-t.scrollThreshold);o=0}if(o>=t.scrollThreshold){do t.click(n.Mouse.State.Buttons.DOWN),o-=t.scrollThreshold;while(o>=t.scrollThreshold);o=0}n.Event.DOMEvent.cancelEvent(u)}window.WheelEvent?e.addEventListener("wheel",d,!1):(e.addEventListener("DOMMouseScroll",d,!1),e.addEventListener("mousewheel",d,!1));var m=(function(){var u=document.createElement("div");if(!("cursor"in u.style))return!1;try{u.style.cursor="url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX///+nxBvIAAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==) 0 0, auto"}catch{return!1}return/\\burl\\([^()]*\\)\\s+0\\s+0\\b/.test(u.style.cursor||"")})();this.setCursor=function(u,h,S){if(m){var E=u.toDataURL("image/png");return e.style.cursor="url("+E+") "+h+" "+S+", auto",!0}return!1}};n.Mouse.State=function(e){var t=function(s,o,c,d,m,u,h){return{x:s,y:o,left:c,middle:d,right:m,up:u,down:h}};arguments.length>1?e=t.apply(this,arguments):e=e||{},n.Position.call(this,e),this.left=e.left||!1,this.middle=e.middle||!1,this.right=e.right||!1,this.up=e.up||!1,this.down=e.down||!1};n.Mouse.State.Buttons={LEFT:"left",MIDDLE:"middle",RIGHT:"right",UP:"up",DOWN:"down"};n.Mouse.Event=function(e,t,a){n.Event.DOMEvent.call(this,e,a);var s="on"+this.type;this.state=t,this.invokeLegacyHandler=function(c){c[s]&&(this.preventDefault(),this.stopPropagation(),c[s](this.state))}};n.Mouse.Event.Target=function(){n.Event.Target.call(this),this.currentState=new n.Mouse.State,this.press=function(t,a){this.currentState[t]||(this.currentState[t]=!0,this.dispatch(new n.Mouse.Event("mousedown",this.currentState,a)))},this.release=function(t,a){this.currentState[t]&&(this.currentState[t]=!1,this.dispatch(new n.Mouse.Event("mouseup",this.currentState,a)))},this.click=function(t,a){this.press(t,a),this.release(t,a)},this.move=function(t,a){(this.currentState.x!==t.x||this.currentState.y!==t.y)&&(this.currentState.x=t.x,this.currentState.y=t.y,this.dispatch(new n.Mouse.Event("mousemove",this.currentState,a)))},this.out=function(t){this.dispatch(new n.Mouse.Event("mouseout",this.currentState,t))},this.reset=function(t){for(var a in n.Mouse.State.Buttons)this.release(n.Mouse.State.Buttons[a],t)}};n.Mouse.Touchpad=function(e){n.Mouse.Event.Target.call(this);var t=this;this.scrollThreshold=20*(window.devicePixelRatio||1),this.clickTimingThreshold=250,this.clickMoveThreshold=10*(window.devicePixelRatio||1),this.currentState=new n.Mouse.State;var a=0,s=0,o=0,c=0,d=0,m={1:"left",2:"right",3:"middle"},u=!1,h=null;e.addEventListener("touchend",function(S){if(S.preventDefault(),u&&S.touches.length===0){var E=new Date().getTime(),g=m[a];t.currentState[g]&&(t.release(g,S),h&&(window.clearTimeout(h),h=null)),E-c<=t.clickTimingThreshold&&d<t.clickMoveThreshold&&(t.press(g,S),h=window.setTimeout(function(){t.release(g,S),u=!1},t.clickTimingThreshold)),h||(u=!1)}},!1),e.addEventListener("touchstart",function(S){if(S.preventDefault(),a=Math.min(S.touches.length,3),h&&(window.clearTimeout(h),h=null),!u){u=!0;var E=S.touches[0];s=E.clientX,o=E.clientY,c=new Date().getTime(),d=0}},!1),e.addEventListener("touchmove",function(S){S.preventDefault();var E=S.touches[0],g=E.clientX-s,I=E.clientY-o;if(d+=Math.abs(g)+Math.abs(I),a===1){var P=d/(new Date().getTime()-c),C=1+P,l=new n.Position(t.currentState);l.x+=g*C,l.y+=I*C,l.x=Math.min(Math.max(0,l.x),e.offsetWidth-1),l.y=Math.min(Math.max(0,l.y),e.offsetHeight-1),t.move(l,S),s=E.clientX,o=E.clientY}else if(a===2&&Math.abs(I)>=t.scrollThreshold){var v;I>0?v="down":v="up",t.click(v,S),s=E.clientX,o=E.clientY}},!1)};n.Mouse.Touchscreen=function(e){n.Mouse.Event.Target.call(this);var t=this,a=!1,s=null,o=null,c=null,d=null;this.scrollThreshold=20*(window.devicePixelRatio||1),this.clickTimingThreshold=250,this.clickMoveThreshold=16*(window.devicePixelRatio||1),this.longPressThreshold=500;function m(S){var E=S.touches[0]||S.changedTouches[0],g=E.clientX-s,I=E.clientY-o;return Math.sqrt(g*g+I*I)>=t.clickMoveThreshold}function u(S){var E=S.touches[0];a=!0,s=E.clientX,o=E.clientY}function h(){window.clearTimeout(c),window.clearTimeout(d),a=!1}e.addEventListener("touchend",function(S){if(a){if(S.touches.length!==0||S.changedTouches.length!==1){h();return}if(window.clearTimeout(d),t.release(n.Mouse.State.Buttons.LEFT,S),!m(S)&&(S.preventDefault(),!t.currentState.left)){var E=S.changedTouches[0];t.move(n.Position.fromClientPosition(e,E.clientX,E.clientY)),t.press(n.Mouse.State.Buttons.LEFT,S),c=window.setTimeout(function(){t.release(n.Mouse.State.Buttons.LEFT,S),h()},t.clickTimingThreshold)}}},!1),e.addEventListener("touchstart",function(S){if(S.touches.length!==1){h();return}S.preventDefault(),u(S),window.clearTimeout(c),d=window.setTimeout(function(){var E=S.touches[0];t.move(n.Position.fromClientPosition(e,E.clientX,E.clientY)),t.click(n.Mouse.State.Buttons.RIGHT,S),h()},t.longPressThreshold)},!1),e.addEventListener("touchmove",function(S){if(a){if(m(S)&&window.clearTimeout(d),S.touches.length!==1){h();return}if(t.currentState.left){S.preventDefault();var E=S.touches[0];t.move(n.Position.fromClientPosition(e,E.clientX,E.clientY),S)}}},!1)};var n=n||{},n=n||{};n.Object=function(e,t){var a=this,s={},o=function(m){var u=s[m];if(!u)return null;var h=u.shift();return u.length===0&&delete s[m],h},c=function(m,u){var h=s[m];h||(h=[],s[m]=h),h.push(u)};this.index=t,this.onbody=function(m,u,h){var S=o(h);S&&S(m,u)},this.onundefine=null,this.requestInputStream=function(m,u){u&&c(m,u),e.requestObjectInputStream(a.index,m)},this.createOutputStream=function(m,u){return e.createObjectOutputStream(a.index,m,u)}};n.Object.ROOT_STREAM="/";n.Object.STREAM_INDEX_MIMETYPE="application/vnd.glyptodon.guacamole.stream-index+json";var n=n||{};n.OnScreenKeyboard=function(r){var e=this,t={},a={},s=[],o=function(y,w){y.classList?y.classList.add(w):y.className+=" "+w},c=function(y,w){y.classList?y.classList.remove(w):y.className=y.className.replace(/([^ ]+)[ ]*/g,function(R,M){return M===w?"":R})},d=0,m=function(){d=e.touchMouseThreshold},u=function(y,w,T,R){this.width=w,this.height=T,this.scale=function(M){y.style.width=w*M+"px",y.style.height=T*M+"px",R&&(y.style.lineHeight=T*M+"px",y.style.fontSize=M+"px")}},h=function(y){for(var w=0;w<y.length;w++){var T=y[w];if(!(T in t))return!1}return!0},S=function(y){var w=e.keys[y];if(!w)return null;for(var T=w.length-1;T>=0;T--){var R=w[T];if(h(R.requires))return R}return null},E=function(y,w){if(!a[y]){o(w,"guac-keyboard-pressed");var T=S(y);if(T.modifier){var R="guac-keyboard-modifier-"+l(T.modifier),M=t[T.modifier];M===void 0?(o(I,R),t[T.modifier]=T.keysym,T.keysym&&e.onkeydown&&e.onkeydown(T.keysym)):(c(I,R),delete t[T.modifier],M&&e.onkeyup&&e.onkeyup(M))}else e.onkeydown&&e.onkeydown(T.keysym);a[y]=!0}},g=function(y,w){if(a[y]){c(w,"guac-keyboard-pressed");var T=S(y);!T.modifier&&e.onkeyup&&e.onkeyup(T.keysym),a[y]=!1}},I=document.createElement("div");I.className="guac-keyboard",I.onselectstart=I.onmousemove=I.onmouseup=I.onmousedown=function(y){return d&&d--,y.stopPropagation(),!1},this.touchMouseThreshold=3,this.onkeydown=null,this.onkeyup=null,this.layout=new n.OnScreenKeyboard.Layout(r),this.getElement=function(){return I},this.resize=function(x){for(var y=Math.floor(x*10/e.layout.width)/10,w=0;w<s.length;w++){var T=s[w];T.scale(y)}};var P=function(y,w){if(w instanceof Array){for(var T=[],R=0;R<w.length;R++)T.push(new n.OnScreenKeyboard.Key(w[R],y));return T}return typeof w=="number"?[new n.OnScreenKeyboard.Key({name:y,keysym:w})]:typeof w=="string"?[new n.OnScreenKeyboard.Key({name:y,title:w})]:[new n.OnScreenKeyboard.Key(w,y)]},C=function(y){var w={};for(var T in r.keys)w[T]=P(T,y[T]);return w};this.keys=C(r.keys);var l=function(y){var w=y.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[^A-Za-z0-9]+/g,"-").toLowerCase();return w},v=function x(y,w,T){var R,M=document.createElement("div");if(T&&o(M,"guac-keyboard-"+l(T)),w instanceof Array)for(o(M,"guac-keyboard-group"),R=0;R<w.length;R++)x(M,w[R]);else if(w instanceof Object){o(M,"guac-keyboard-group");var D=Object.keys(w).sort();for(R=0;R<D.length;R++){var T=D[R];x(M,w[T],T)}}else if(typeof w=="number")o(M,"guac-keyboard-gap"),s.push(new u(M,w,w));else if(typeof w=="string"){var F=w;F.length===1&&(F="0x"+F.charCodeAt(0).toString(16)),o(M,"guac-keyboard-key-container");var H=document.createElement("div");H.className="guac-keyboard-key guac-keyboard-key-"+l(F);var i=e.keys[w];if(i)for(R=0;R<i.length;R++){var f=i[R],p=document.createElement("div");p.className="guac-keyboard-cap",p.textContent=f.title;for(var k=0;k<f.requires.length;k++){var A=f.requires[k];o(p,"guac-keyboard-requires-"+l(A)),o(H,"guac-keyboard-uses-"+l(A))}H.appendChild(p)}M.appendChild(H),s.push(new u(M,e.layout.keyWidths[w]||1,1,!0));var L=function(Y){Y.preventDefault(),d=e.touchMouseThreshold,E(w,H)},_=function(Y){Y.preventDefault(),d=e.touchMouseThreshold,g(w,H)},b=function(Y){Y.preventDefault(),d===0&&E(w,H)},O=function(Y){Y.preventDefault(),d===0&&g(w,H)};H.addEventListener("touchstart",L,!0),H.addEventListener("touchend",_,!0),H.addEventListener("mousedown",b,!0),H.addEventListener("mouseup",O,!0),H.addEventListener("mouseout",O,!0)}y.appendChild(M)};v(I,r.layout)};n.OnScreenKeyboard.Layout=function(r){this.language=r.language,this.type=r.type,this.keys=r.keys,this.layout=r.layout,this.width=r.width,this.keyWidths=r.keyWidths||{}};n.OnScreenKeyboard.Key=function(r,e){this.name=e||r.name,this.title=r.title||this.name,this.keysym=r.keysym||(function(a){if(!a||a.length!==1)return null;var s=a.charCodeAt(0);return s>=0&&s<=255?s:s>=256&&s<=1114111?16777216|s:null})(this.title),this.modifier=r.modifier,this.requires=r.requires||[]};var n=n||{};n.OutputStream=function(r,e){var t=this;this.index=e,this.onack=null,this.sendBlob=function(a){r.sendBlob(t.index,a)},this.sendEnd=function(){r.endStream(t.index)}};var n=n||{};n.Parser=function(){var e=this,t="",a=[],s=-1,o=0,c=0,d=4096,m=65536;this.receive=function(h,S){for(S?t=h:(o>d&&s>=o&&(t=t.substring(o),s-=o,o=0),t.length?t+=h:t=h);s<t.length;){if(s>=o){var E=n.Parser.codePointCount(t,o,s);if(E<c){s+=c-E;continue}else if(c&&t.codePointAt(s-1)>=m){s++;continue}var g=t.substring(o,s),I=t.substring(s,s+1);if(a.push(g),I===";"){var P=a.shift();e.oninstruction!==null&&e.oninstruction(P,a),a=[],!S&&s+1===t.length&&(s=-1,t="")}else if(I!==",")throw new Error(\'Element terminator of instruction was not ";" nor ",".\');o=s+1}var C=t.indexOf(".",o);if(C!==-1){if(c=parseInt(t.substring(s+1,C)),isNaN(c))throw new Error("Non-numeric character in element length.");o=C+1,s=o+c}else{o=t.length;break}}},this.oninstruction=null};n.Parser.codePointCount=function(e,t,a){e=e.substring(t||0,a);var s=e.match(/[\\uD800-\\uDBFF][\\uDC00-\\uDFFF]/g);return e.length-(s?s.length:0)};n.Parser.toInstruction=function(e){for(var t=function(c){var d=""+c;return n.Parser.codePointCount(d)+"."+d},a=t(e[0]),s=1;s<e.length;s++)a+=","+t(e[s]);return a+";"};var n=n||{};n.Position=function(e){e=e||{},this.x=e.x||0,this.y=e.y||0,this.fromClientPosition=function(a,s,o){this.x=s-a.offsetLeft,this.y=o-a.offsetTop;for(var c=a.offsetParent;c&&c!==document.body;)this.x-=c.offsetLeft-c.scrollLeft,this.y-=c.offsetTop-c.scrollTop,c=c.offsetParent;if(c){var d=document.body.scrollLeft||document.documentElement.scrollLeft,m=document.body.scrollTop||document.documentElement.scrollTop;this.x-=c.offsetLeft-d,this.y-=c.offsetTop-m}}};n.Position.fromClientPosition=function(e,t,a){var s=new n.Position;return s.fromClientPosition(e,t,a),s};var n=n||{};n.RawAudioFormat=function(e){this.bytesPerSample=e.bytesPerSample,this.channels=e.channels,this.rate=e.rate};n.RawAudioFormat.parse=function(e){var t,a=null,s=1;if(e.substring(0,9)==="audio/L8;")e=e.substring(9),t=1;else if(e.substring(0,10)==="audio/L16;")e=e.substring(10),t=2;else return null;for(var o=e.split(","),c=0;c<o.length;c++){var d=o[c],m=d.indexOf("=");if(m===-1)return null;var u=d.substring(0,m),h=d.substring(m+1);switch(u){case"channels":s=parseInt(h);break;case"rate":a=parseInt(h);break;default:return null}}return a===null?null:new n.RawAudioFormat({bytesPerSample:t,channels:s,rate:a})};var n=n||{};n.SessionRecording=function(e,t){t===void 0&&(t=1e3);var a=this,s,o=null,c=262144,d=16384,m=5e3,u=[],h=0,S=new n.SessionRecording._PlaybackTunnel,E=new n.Client(S),g=-1,I=null,P=null,C=0,l=null,v=0,x=0,y=!1,w=null,T=null,R=null,M=function(N,V,z){if(!(y&&N===s)){var X=new n.Parser;X.oninstruction=V;var W=0,$=new FileReader,fe=function(){if(!(y&&N===s)){if($.readyState===2)try{X.receive($.result)}catch(ie){a.onerror&&a.onerror(ie.message);return}if(W>=N.size)z&&z();else{var re=N.slice(W,W+c);W+=re.size,$.readAsText(re)}}};$.onload=fe,fe()}},D=function(U){for(var N=U.length,V=U.length-1;V>=0;V--){var z=U.charCodeAt(V);z>127&&z<=2047?N++:z>2047&&z<=65535&&(N+=2),z>=56320&&z<=57343&&V--}return N},F=function(N){for(var V=D(N)+3,z=n.Parser.codePointCount(N);z>=10;)V++,z=Math.floor(z/10);return V};E.connect(),E.getDisplay().showCursor(!1);var H=null;function i(U){H=new n.KeyEventInterpreter(U)}var f=function(N,V){x+=F(N);for(var z=0;z<V.length;z++)x+=F(V[z]);if(N==="sync"){var X=parseInt(V[0]),W=new n.SessionRecording._Frame(X,v,x);u.push(W),v=x,u.length===1&&i(X),(u.length===1||x-u[h].start>=d&&X-u[h].timestamp>=m)&&(W.keyframe=!0,h=u.length-1),a.onprogress&&a.onprogress(a.getDuration(),x)}else N==="key"&&H.handleKeyEvent(V)},p=function(){a.onload&&a.onload()};if(e instanceof Blob)s=e,M(s,f,p);else{o=e,s=new Blob;var k=!1,A="";o.oninstruction=function(N,V){A+=N.length+"."+N,V.forEach(function(X){A+=","+X.length+"."+X}),A+=";",A.length>=c&&(s=new Blob([s,A]),A=""),f(N,V)},o.onerror=function(N){k=!0,a.onerror&&a.onerror(N.message)},o.onstatechange=function(N){N===n.Tunnel.State.CLOSED&&(A.length&&(s=new Blob([s,A]),A=""),a.onkeyevents&&a.onkeyevents(H.getEvents()),k||p())}}var L=function(N){return u.length===0?0:N-u[0].timestamp},_=function U(N,V,z){if(N===V){if(N===0)return N;if(L(u[N].timestamp)>z)return N-1}var X=Math.floor((N+V)/2),W=L(u[X].timestamp);return z<W&&X>N?U(N,X-1,z):z>W&&X<V?U(X+1,V,z):X},b=function(N,V){var z=u[N];M(s.slice(z.start,z.end),function(W,$){S.receiveInstruction(W,$)},function(){z.keyframe&&!z.clientState&&E.exportState(function($){z.clientState=new Blob([JSON.stringify($)])}),g=N,V&&V()})},O=function(N,V,z){B();for(var X=l={aborted:!1},W=N,$=function re(){a.onseek&&g>W&&(C=L(u[g].timestamp),a.onseek(C,g-W,N-W)),!X.aborted&&(g<N?b(g+1,re):V())},fe=function(){var ie=z?Math.max(z-new Date().getTime(),0):0;ie?(T&&clearTimeout(T),T=window.setTimeout(function(){T=null,$()},ie)):$()};W>=0;W--){var we=u[W];if(W===g)break;if(we.clientState){we.clientState.text().then(function(ie){E.importState(JSON.parse(ie)),g=W,fe()});return}}fe()},B=function(){l&&(l.aborted=!0,l=null)},Y=function U(){if(a.isPlaying())if(g+1<u.length){var N=u[g+1],V=Date.now()-P,z=L(N.timestamp)-I,X=z-V,W=t>=0?t*Math.floor((C+t)/t)-C:X;X<=W?O(g+1,function(){R=Date.now(),U()},Date.now()+X):(T&&window.clearTimeout(T),T=window.setTimeout(function(){T=null,C+=W,a.onseek&&a.onseek(C),R=Date.now(),U()},W))}else a.pause()};this.onload=null,this.onerror=null,this.onabort=null,this.onprogress=null,this.onplay=null,this.onpause=null,this.onkeyevents=null,this.onseek=null,this.connect=function(N){o&&o.connect(N)},this.disconnect=function(){o&&o.disconnect()},this.abort=function(){y||(y=!0,a.onabort&&a.onabort(),o&&o.disconnect())},this.getDisplay=function(){return E.getDisplay()},this.isPlaying=function(){return!!P},this.getPosition=function(){return C},this.getDuration=function(){return u.length===0?0:L(u[u.length-1].timestamp)},this.play=function(){!a.isPlaying()&&g+1<u.length&&(a.onplay&&a.onplay(),I=C,P=Date.now(),R=Date.now(),Y())},this.seek=function(N,V){if(u.length!==0){a.cancel();var z=a.isPlaying();a.pause(),w=function(){w=null,z&&(a.play(),z=null),V&&V()};var X=_(0,u.length-1,N);O(X,function(){C=N,a.onseek&&a.onseek(N),w()})}},this.cancel=function(){w&&(B(),w())},this.pause=function(){B(),T&&clearTimeout(T),C+=Date.now()-R,a.isPlaying()&&(a.onpause&&a.onpause(),R=null,I=null,P=null)}};n.SessionRecording._Frame=function(e,t,a){this.keyframe=!1,this.timestamp=e,this.start=t,this.end=a,this.clientState=null};n.SessionRecording._PlaybackTunnel=function(){var e=this;this.connect=function(a){},this.sendMessage=function(a){},this.disconnect=function(){},this.receiveInstruction=function(a,s){e.oninstruction&&e.oninstruction(a,s)}};var n=n||{};n.Status=function(r,e){var t=this;this.code=r,this.message=e,this.isError=function(){return t.code<0||t.code>255}};n.Status.Code={SUCCESS:0,UNSUPPORTED:256,SERVER_ERROR:512,SERVER_BUSY:513,UPSTREAM_TIMEOUT:514,UPSTREAM_ERROR:515,RESOURCE_NOT_FOUND:516,RESOURCE_CONFLICT:517,RESOURCE_CLOSED:518,UPSTREAM_NOT_FOUND:519,UPSTREAM_UNAVAILABLE:520,SESSION_CONFLICT:521,SESSION_TIMEOUT:522,SESSION_CLOSED:523,CLIENT_BAD_REQUEST:768,CLIENT_UNAUTHORIZED:769,CLIENT_FORBIDDEN:771,CLIENT_TIMEOUT:776,CLIENT_OVERRUN:781,CLIENT_BAD_TYPE:783,CLIENT_TOO_MANY:797};n.Status.Code.fromHTTPCode=function(e){switch(e){case 400:return n.Status.Code.CLIENT_BAD_REQUEST;case 403:return n.Status.Code.CLIENT_FORBIDDEN;case 404:return n.Status.Code.RESOURCE_NOT_FOUND;case 429:return n.Status.Code.CLIENT_TOO_MANY;case 503:return n.Status.Code.SERVER_BUSY}return n.Status.Code.SERVER_ERROR};n.Status.Code.fromWebSocketCode=function(e){switch(e){case 1e3:return n.Status.Code.SUCCESS;case 1006:case 1015:return n.Status.Code.UPSTREAM_NOT_FOUND;case 1001:case 1012:case 1013:case 1014:return n.Status.Code.UPSTREAM_UNAVAILABLE}return n.Status.Code.SERVER_ERROR};var n=n||{};n.StringReader=function(r){var e=this,t=new n.UTF8Parser,a=new n.ArrayBufferReader(r);a.ondata=function(s){var o=t.decode(s);e.ontext&&e.ontext(o)},a.onend=function(){e.onend&&e.onend()},this.ontext=null,this.onend=null};var n=n||{};n.StringWriter=function(r){var e=this,t=new n.ArrayBufferWriter(r),a=new Uint8Array(8192),s=0;t.onack=function(m){e.onack&&e.onack(m)};function o(m){if(s+m>=a.length){var u=new Uint8Array((s+m)*2);u.set(a),a=u}s+=m}function c(m){var u,h;if(m<=127)u=0,h=1;else if(m<=2047)u=192,h=2;else if(m<=65535)u=224,h=3;else if(m<=2097151)u=240,h=4;else{c(65533);return}o(h);for(var S=s-1,E=1;E<h;E++)a[S--]=128|m&63,m>>=6;a[S]=u|m}function d(m){for(var u=0;u<m.length;u++){var h=m.charCodeAt(u);c(h)}if(s>0){var S=a.subarray(0,s);return s=0,S}}this.sendText=function(m){m.length&&t.sendData(d(m))},this.sendEnd=function(){t.sendEnd()},this.onack=null};var n=n||{};n.Touch=function(e){n.Event.Target.call(this);var t=this,a=new n.IntegerPool,s={},o=Math.floor(16*window.devicePixelRatio);this.touches={},this.activeTouches=0;var c=function(u){return u in s?s[u]:s[u]=a.next()},d=function(u){var h=c(u);return delete s[u],a.free(h),h};e.addEventListener("touchstart",function(u){for(var h=0;h<u.changedTouches.length;h++){var S=u.changedTouches[h],E=c(S.identifier);if(!t.touches[E]){var g=t.touches[E]=new n.Touch.State({id:E,radiusX:S.radiusX||o,radiusY:S.radiusY||o,angle:S.angle||0,force:S.force||1});t.activeTouches++,g.fromClientPosition(e,S.clientX,S.clientY),t.dispatch(new n.Touch.Event("touchmove",u,g))}}},!1),e.addEventListener("touchmove",function(u){for(var h=0;h<u.changedTouches.length;h++){var S=u.changedTouches[h],E=c(S.identifier),g=t.touches[E];g&&(S.force&&(g.force=S.force),g.angle=S.angle||0,g.radiusX=S.radiusX||o,g.radiusY=S.radiusY||o,g.fromClientPosition(e,S.clientX,S.clientY),t.dispatch(new n.Touch.Event("touchmove",u,g)))}},!1),e.addEventListener("touchend",function(u){for(var h=0;h<u.changedTouches.length;h++){var S=u.changedTouches[h],E=d(S.identifier),g=t.touches[E];g&&(delete t.touches[E],t.activeTouches--,g.force=0,g.fromClientPosition(e,S.clientX,S.clientY),t.dispatch(new n.Touch.Event("touchend",u,g)))}},!1)};n.Touch.State=function(e){e=e||{},n.Position.call(this,e),this.id=e.id||0,this.radiusX=e.radiusX||0,this.radiusY=e.radiusY||0,this.angle=e.angle||0,this.force=e.force||1};n.Touch.Event=function(e,t,a){n.Event.DOMEvent.call(this,e,[t]),this.state=a};var n=n||{};n.Tunnel=function(){this.connect=function(r){},this.disconnect=function(){},this.sendMessage=function(r){},this.setState=function(r){r!==this.state&&(this.state=r,this.onstatechange&&this.onstatechange(r))},this.setUUID=function(e){this.uuid=e,this.onuuid&&this.onuuid(e)},this.isConnected=function(){return this.state===n.Tunnel.State.OPEN||this.state===n.Tunnel.State.UNSTABLE},this.state=n.Tunnel.State.CLOSED,this.receiveTimeout=15e3,this.unstableThreshold=1500,this.uuid=null,this.onuuid=null,this.onerror=null,this.onstatechange=null,this.oninstruction=null};n.Tunnel.INTERNAL_DATA_OPCODE="";n.Tunnel.State={CONNECTING:0,OPEN:1,CLOSED:2,UNSTABLE:3};n.HTTPTunnel=function(r,e,t){var a=this,s=r+"?connect",o=r+"?read:",c=r+"?write:",d=1,m=0,u=d,h=!1,S="",E=!!e,g=null,I=null,P=null,C=500,l=t||{},v="Guacamole-Tunnel-Token",x=null;function y(i,f){for(var p in f)i.setRequestHeader(p,f[p])}var w=function(){window.clearTimeout(g),window.clearTimeout(I),a.state===n.Tunnel.State.UNSTABLE&&a.setState(n.Tunnel.State.OPEN),g=window.setTimeout(function(){T(new n.Status(n.Status.Code.UPSTREAM_TIMEOUT,"Server timeout."))},a.receiveTimeout),I=window.setTimeout(function(){a.setState(n.Tunnel.State.UNSTABLE)},a.unstableThreshold)};function T(i){window.clearTimeout(g),window.clearTimeout(I),window.clearInterval(P),a.state!==n.Tunnel.State.CLOSED&&(i.code!==n.Status.Code.SUCCESS&&a.onerror&&(a.state===n.Tunnel.State.CONNECTING||i.code!==n.Status.Code.RESOURCE_NOT_FOUND)&&a.onerror(i),h=!1,a.setState(n.Tunnel.State.CLOSED))}this.sendMessage=function(){a.isConnected()&&arguments.length&&(S+=n.Parser.toInstruction(arguments),h||R())};function R(){if(a.isConnected())if(S.length>0){h=!0;var i=new XMLHttpRequest;i.open("POST",c+a.uuid),i.withCredentials=E,y(i,l),i.setRequestHeader("Content-type","application/octet-stream"),i.setRequestHeader(v,x),i.onreadystatechange=function(){i.readyState===4&&(w(),i.status!==200?M(i):R())},i.send(S),S=""}else h=!1}function M(i){var f=parseInt(i.getResponseHeader("Guacamole-Status-Code"));if(f){var p=i.getResponseHeader("Guacamole-Error-Message");T(new n.Status(f,p))}else i.status?T(new n.Status(n.Status.Code.fromHTTPCode(i.status),i.statusText)):T(new n.Status(n.Status.Code.UPSTREAM_NOT_FOUND))}function D(i){var f=null,p=null,k=0,A=new n.Parser;A.oninstruction=function _(b,O){b===n.Tunnel.INTERNAL_DATA_OPCODE&&O.length===0?(A=new n.Parser,A.oninstruction=_,f&&clearInterval(f),i.onreadystatechange=null,i.abort(),p&&D(p)):b!==n.Tunnel.INTERNAL_DATA_OPCODE&&a.oninstruction&&a.oninstruction(b,O)};function L(){if(!a.isConnected()){f!==null&&clearInterval(f);return}if(!(i.readyState<2)){var _;try{_=i.status}catch{_=200}if(!p&&_===200&&(p=H()),i.readyState===3||i.readyState===4){if(w(),u===d&&(i.readyState===3&&!f?f=setInterval(L,30):i.readyState===4&&f&&clearInterval(f)),i.status===0){a.disconnect();return}else if(i.status!==200){M(i);return}var b;try{b=i.responseText}catch{return}try{A.receive(b,!0)}catch(O){T(new n.Status(n.Status.Code.SERVER_ERROR,O.message));return}}}}u===d?i.onreadystatechange=function(){i.readyState===3&&(k++,k>=2&&(u=m,i.onreadystatechange=L)),L()}:i.onreadystatechange=L,L()}var F=0;function H(){var i=new XMLHttpRequest;return i.open("GET",o+a.uuid+":"+F++),i.setRequestHeader(v,x),i.withCredentials=E,y(i,l),i.send(null),i}this.connect=function(i){w(),a.setState(n.Tunnel.State.CONNECTING);var f=new XMLHttpRequest;f.onreadystatechange=function(){if(f.readyState===4){if(f.status!==200){M(f);return}if(w(),a.setUUID(f.responseText),x=f.getResponseHeader(v),!x){T(new n.Status(n.Status.Code.UPSTREAM_NOT_FOUND));return}a.setState(n.Tunnel.State.OPEN),P=setInterval(function(){a.sendMessage("nop")},C),D(H())}},f.open("POST",s,!0),f.withCredentials=E,y(f,l),f.setRequestHeader("Content-type","application/x-www-form-urlencoded; charset=UTF-8"),f.send(i)},this.disconnect=function(){T(new n.Status(n.Status.Code.SUCCESS,"Manually closed."))}};n.HTTPTunnel.prototype=new n.Tunnel;n.WebSocketTunnel=function(r){var e=this,t=null,a=null,s=null,o=null,c=null,d={"http:":"ws:","https:":"wss:"},m=500,u=0;if(r.substring(0,3)!=="ws:"&&r.substring(0,4)!=="wss:"){var h=d[window.location.protocol];if(r.substring(0,1)==="/")r=h+"//"+window.location.host+r;else{var S=window.location.pathname.lastIndexOf("/"),E=window.location.pathname.substring(0,S+1);r=h+"//"+window.location.host+E+r}}var g=function(){var l=new Date().getTime();e.sendMessage(n.Tunnel.INTERNAL_DATA_OPCODE,"ping",l),u=l},I=function(){window.clearTimeout(s),window.clearTimeout(o),window.clearTimeout(c),e.state===n.Tunnel.State.UNSTABLE&&e.setState(n.Tunnel.State.OPEN),s=window.setTimeout(function(){P(new n.Status(n.Status.Code.UPSTREAM_TIMEOUT,"Server timeout."))},e.receiveTimeout),o=window.setTimeout(function(){e.setState(n.Tunnel.State.UNSTABLE)},e.unstableThreshold);var l=new Date().getTime(),v=Math.max(u+m-l,0);v>0?c=window.setTimeout(g,v):g()};function P(C){window.clearTimeout(s),window.clearTimeout(o),window.clearTimeout(c),e.state!==n.Tunnel.State.CLOSED&&(C.code!==n.Status.Code.SUCCESS&&e.onerror&&e.onerror(C),e.setState(n.Tunnel.State.CLOSED),a.close())}this.sendMessage=function(C){e.isConnected()&&arguments.length&&a.send(n.Parser.toInstruction(arguments))},this.connect=function(C){I(),e.setState(n.Tunnel.State.CONNECTING),t=new n.Parser,t.oninstruction=function(v,x){e.uuid===null&&(v===n.Tunnel.INTERNAL_DATA_OPCODE&&x.length===1&&e.setUUID(x[0]),e.setState(n.Tunnel.State.OPEN)),v!==n.Tunnel.INTERNAL_DATA_OPCODE&&e.oninstruction&&e.oninstruction(v,x)},a=new WebSocket(r+"?"+C,"guacamole"),a.onopen=function(l){I()},a.onclose=function(l){l.reason?P(new n.Status(parseInt(l.reason),l.reason)):l.code?P(new n.Status(n.Status.Code.fromWebSocketCode(l.code))):P(new n.Status(n.Status.Code.UPSTREAM_NOT_FOUND))},a.onmessage=function(l){I();try{t.receive(l.data)}catch(v){P(new n.Status(n.Status.Code.SERVER_ERROR,v.message))}}},this.disconnect=function(){P(new n.Status(n.Status.Code.SUCCESS,"Manually closed."))}};n.WebSocketTunnel.prototype=new n.Tunnel;n.ChainedTunnel=function(r){for(var e=this,t,a=[],s=null,o=0;o<arguments.length;o++)a.push(arguments[o]);function c(d){e.disconnect=d.disconnect,e.sendMessage=d.sendMessage;var m=function(S){if(S&&S.code===n.Status.Code.UPSTREAM_TIMEOUT)return a=[],null;var E=a.shift();return E&&(d.onerror=null,d.oninstruction=null,d.onstatechange=null,c(E)),E};function u(){d.onstatechange=e.onstatechange,d.oninstruction=e.oninstruction,d.onerror=e.onerror,d.uuid&&e.setUUID(d.uuid),d.onuuid=function(S){e.setUUID(S)},s=d}d.onstatechange=function(h){switch(h){case n.Tunnel.State.OPEN:u(),e.onstatechange&&e.onstatechange(h);break;case n.Tunnel.State.CLOSED:!m()&&e.onstatechange&&e.onstatechange(h);break}},d.oninstruction=function(h,S){u(),e.oninstruction&&e.oninstruction(h,S)},d.onerror=function(h){!m(h)&&e.onerror&&e.onerror(h)},d.connect(t)}this.connect=function(d){t=d;var m=s||a.shift();m?c(m):e.onerror&&e.onerror(n.Status.Code.SERVER_ERROR,"No tunnels to try.")}};n.ChainedTunnel.prototype=new n.Tunnel;n.StaticHTTPTunnel=function(e,t,a){var s=this,o=null,c=a||{};this.size=null,this.sendMessage=function(m){},this.connect=function(m){s.disconnect(),s.setState(n.Tunnel.State.CONNECTING);var u=new n.Parser,h=new n.UTF8Parser;u.oninstruction=function(E,g){s.oninstruction&&s.oninstruction(E,g)},o=new AbortController,fetch(e,{headers:c,credentials:t?"include":"same-origin",signal:o.signal}).then(function(E){if(!E.ok){s.onerror&&s.onerror(new n.Status(n.Status.Code.fromHTTPCode(E.status),E.statusText)),s.disconnect();return}s.size=E.headers.get("Content-Length"),s.setState(n.Tunnel.State.OPEN);var g=E.body.getReader(),I=function P(C){if(C.done){s.disconnect();return}u.receive(h.decode(C.value)),g.read().then(P)};g.read().then(I)})},this.disconnect=function(){o&&(o.abort(),o=null),s.setState(n.Tunnel.State.CLOSED)}};n.StaticHTTPTunnel.prototype=new n.Tunnel;var n=n||{};n.UTF8Parser=function(){var e=0,t=0;this.decode=function(s){for(var o="",c=new Uint8Array(s),d=0;d<c.length;d++){var m=c[d];e===0?(m|127)===127?o+=String.fromCharCode(m):(m|31)===223?(t=m&31,e=1):(m|15)===239?(t=m&15,e=2):(m|7)===247?(t=m&7,e=3):o+="\\uFFFD":(m|63)===191?(t=t<<6|m&63,e--,e===0&&(o+=String.fromCharCode(t))):(e=0,o+="\\uFFFD")}return o}};var n=n||{};n.API_VERSION="1.6.0";var n=n||{};n.VideoPlayer=function(){this.sync=function(){}};n.VideoPlayer.isSupportedType=function(e){return!1};n.VideoPlayer.getSupportedTypes=function(){return[]};n.VideoPlayer.getInstance=function(e,t,a){return null};typeof window<"u"&&(window.Guacamole=n);function Pe(r,e,t){let a=new r.Keyboard(e),s=[new r.Mouse(e),new r.Mouse.Touchscreen(e)],o=!1,c={x:0,y:0},d=g=>{o&&(c={...g},t.sendMouseState(g,!0))};for(let g of s)g.onmousedown=g.onmousemove=g.onmouseup=d;a.onkeydown=g=>o?(t.sendKeyEvent(1,g),!1):!0,a.onkeyup=g=>{o&&t.sendKeyEvent(0,g)};let m=()=>{o&&(a.reset(),(c.left||c.middle||c.right)&&t.sendMouseState({x:c.x,y:c.y},!0),c={x:c.x,y:c.y})},u=()=>{o&&e.focus({preventScroll:!0})},h=g=>{g.key!=="Escape"||!g.ctrlKey||!g.altKey||(g.preventDefault(),g.stopImmediatePropagation(),m(),e.blur())},S=g=>{o&&g.preventDefault()};e.addEventListener("keydown",h,!0),e.addEventListener("pointerdown",u),e.addEventListener("blur",m),e.addEventListener("contextmenu",S),window.addEventListener("blur",m);let E=g=>{g!==o&&(g||m(),o=g,e.tabIndex=o?0:-1,e.style.cursor=o?"":"default",e.style.touchAction=o?"none":"",o?(e.setAttribute("role","application"),e.setAttribute("aria-label","Remote computer. Click to type. Press Control Alt Escape to return to the page.")):(e.removeAttribute("role"),e.removeAttribute("aria-label"),e.blur()))};return E(!1),{set:E,dispose:()=>{E(!1),a.onkeydown=a.onkeyup=null;for(let g of s)g.onmousedown=g.onmousemove=g.onmouseup=null;e.removeEventListener("keydown",h,!0),e.removeEventListener("pointerdown",u),e.removeEventListener("blur",m),e.removeEventListener("contextmenu",S),window.removeEventListener("blur",m)}}}function Xe(r){return r===517||r===521?"conflict":r===519||r===520?"unreachable":"other"}function Le(r,e,t){let a=window.Guacamole,[s,o=""]=r.split("?",2),c=new a.WebSocketTunnel(s),d=new a.Client(c),m=d.getDisplay(),u=m.getElement();e.replaceChildren(u);let h=Pe(a,u,d),S=()=>{let l=m.getWidth();l>0&&m.scale(e.clientWidth/l)};m.onresize=S;let E=new ResizeObserver(S);E.observe(e);let g=!1,I=!1,P=(l,v)=>{g||(g=!0,E.disconnect(),t.lost(l,I?Xe(v):"blocked"))};c.onerror=l=>P(l.message||`Tunnel error ${l.code}`,l.code),d.onerror=l=>P(l.message||`Client error ${l.code}`,l.code),d.onstatechange=l=>{l===3?t.connected():l===5&&P("Disconnected")};let C=window.WebSocket;window.WebSocket=class extends C{constructor(l,v){super(l,v),this.addEventListener("open",()=>I=!0)}};try{d.connect(o)}finally{window.WebSocket=C}return{setInput:l=>{g||h.set(l)},close:(l=!1)=>{h.dispose();let v;if(l&&m.getWidth()>0&&m.getHeight()>0)try{v=m.flatten().toDataURL("image/jpeg",.7),Se(e,v)}catch{v=void 0}v||e.replaceChildren(),g=!0,E.disconnect(),d.onstatechange=null,d.onerror=null,c.onerror=null;try{d.disconnect()}catch{}return v}}}function Se(r,e){let t=new Image;t.src=e,t.alt="The last frame of the computer screen",r.replaceChildren(t)}var Te={sessionId:null,status:"starting",steps:[],text:""},qe=200;function Oe(r){let e=r.replace(/^mcp__[^_]+__/,"").replace(/[_-]+/g," ").trim();return e?e.charAt(0).toUpperCase()+e.slice(1):r}var Je=/^\\[[A-Za-z ]+\\]/,De=160;function je(r){if(!/^[[{]/.test(r))return!1;try{return typeof JSON.parse(r)=="object"}catch{return/^(\\[\\s*[{"\\]]|\\{\\s*")/.test(r)}}function $e(r){let e=r.trim();return!e||Je.test(e)||je(e)?null:e.length>De?`${e.slice(0,De-1)}\\u2026`:e}function Ze(r){let e=r?.title;return typeof e=="string"&&e.trim()?e.trim():void 0}function Qe(r,e){let t=[...r],a=()=>t.at(-1),s=o=>t.find(c=>c.callId===o);for(let o of e)if(o.type==="tool-input-start")o.toolName!=="execute"&&!s(o.toolCallId)&&t.push({title:Oe(o.toolName),callId:o.toolCallId});else if(o.type==="tool-input-available"){let c=Ze(o.input)??(o.toolName==="execute"?void 0:Oe(o.toolName));if(!c)continue;let d=s(o.toolCallId);d?d.title=c:t.push({title:c,callId:o.toolCallId})}else if((o.type==="data-progress"||o.type==="data-status")&&o.data?.text){let c=$e(o.data.text),d=a();if(!c||c===d?.title||c===d?.detail)continue;d?.callId?t[t.length-1]={...d,detail:c}:t.push({title:c})}return t}function Ue(r){let e=s=>s.replace(/[&<>"\']/g,o=>({"&":"&","<":"<",">":">",\'"\':""","\'":"'"})[o]),t=[],a=r.replace(/\\uE000/g,"").replace(/`([^`\\n]+)`/g,(s,o)=>(t.push(`<code>${e(o)}</code>`),`\\uE000${t.length-1}\\uE000`));return e(a).replace(/\\*\\*([^\\n]+?)\\*\\*/g,"<strong>$1</strong>").replace(/\\uE000(\\d+)\\uE000/g,(s,o)=>t[Number(o)])}function Fe(r,e){let t=Qe(r.steps,e.events??[]);return{...r,status:e.status,steps:t.slice(-qe),text:e.text??r.text,approval:e.status==="needs_approval"?e.approval:void 0,error:e.error,playgroundUrl:e.playground_url??r.playgroundUrl}}function q(r){return r.status==="idle"||r.status==="error"}function Ke(r,e){return r.status==="needs_approval"||q(r)&&e}var Ne="Sai started another task on this computer, so it has the mouse and keyboard again.",et="Sai was restarted, so this view can\'t tell whether the computer is free. Send Sai a task instead.";function Be(r){if(r.archived)return Ne;if(r.expired)return et;if(r.status!=="idle"&&r.status!=="error")return Ne}function Ee(r,e){return q(r)&&(e==="no_tunnel"||e==="unreachable")}function He(r){return r.status==="starting"?"Starting Sai\\u2026":r.status==="needs_approval"?"Sai needs your OK to continue":r.status==="error"?"Sai stopped with an error":r.status==="idle"?"Done":r.steps.at(-1)?.title??"Sai is working\\u2026"}var j=window.parent===window?new le:new ue;j instanceof le&&document.documentElement.classList.add("standalone");var K=Te,ae,ye=!1,ve=null,he=null,pe=null,Q,oe=null,ce=!1,de=!1,Z=!1,te="inline",ge=[],tt=new Set(["Claude"]),Ve="",ne=r=>new Promise(e=>setTimeout(e,r)),G=r=>document.getElementById(r),Ge=r=>r.replace(/[&<>"\']/g,e=>({"&":"&","<":"<",">":">",\'"\':""","\'":"'"})[e]);function J(){let r=Ke(K,Z);oe?.setInput(de&&r),G("input-note").hidden=!de,G("input-note").textContent=r?"Click the screen to use the mouse and keyboard. Control+Alt+Escape gives the keys back.":"Sai is working. Input is paused until it finishes.",G("headline").textContent=He(K),G("dot").className=`dot ${K.status}`;let e=K.steps.slice(-12);G("steps").innerHTML=e.map(a=>`<li>${Ge(a.title)}${a.detail?`<span class="detail">${Ge(a.detail)}</span>`:""}</li>`).join(""),G("steps-more").textContent=K.steps.length>e.length?`${K.steps.length-e.length} earlier steps`:"",G("answer").hidden=!(q(K)&&K.text),G("answer").innerHTML=Ue(K.text),G("error").hidden=!K.error,G("error").textContent=K.error??"";let t=K.approval;G("approval").hidden=!t,t&&(G("approval-title").textContent=t.title,G("approval-text").textContent=t.command?`${t.description}\n${t.command}`:t.description,G("approve").hidden=G("approve-task").hidden=G("deny").hidden=t.isLinkOnly,G("open-approval").hidden=!t.isLinkOnly||!t.approvalUrl),G("live").hidden=!K.playgroundUrl,G("screen-wrap").hidden=!ve||q(K)&&!Q&&!oe&&!Z,G("screen").hidden=xe&&!Q,document.documentElement.dataset.mode=te,G("pin").hidden=te!=="inline"||!ge.includes("pip"),G("expand").hidden=te!=="inline"||!ge.includes("fullscreen"),G("restore").hidden=te==="inline",G("watch-here").hidden=!se||q(K),G("use").hidden=!q(K)||!ve||ce||xe||se||Z,G("stop-use").hidden=!Z,G("popout").hidden=!(j instanceof ue)||!pe||ge.includes("pip")||!tt.has(Ve),j.sizeChanged(document.documentElement.scrollHeight)}function Ce(r){if(r.structuredContent)return r.structuredContent;let e=r.content?.find(t=>t.type==="text")?.text;try{return e?JSON.parse(e):void 0}catch{return}}function ze(r,e){r?(K={...K,status:r.status,steps:r.steps,text:r.text,error:r.error},r.frame&&(Q=r.frame,Se(G("screen"),r.frame))):K={...K,status:"idle",text:e??""},J()}function We(){if(!he)return;let r={status:K.status,steps:K.steps.map(({title:e,detail:t})=>({title:e,...t&&{detail:t}})),text:K.text,...K.error&&{error:K.error},...Q&&{frame:Q}};j.callTool("sai_view_save",{task_id:he,snapshot:r}).catch(()=>{})}async function Ie(r){if(ye||!K.sessionId){r(ye&&Z);return}ye=!0;let e=!0,t=a=>{e&&r(a),e=!1};try{for(;K.sessionId&&(!q(K)||Z);){let a=Date.now(),s=await j.callTool("sai_view_poll",{session_id:K.sessionId,...ae&&{cursor:ae},...he&&{task_id:he}}),o=Ce(s);if(s.isError||!o){await ne(5e3);continue}if(q(K)){let c=Be(o);if(c){me(c),t(!1);return}ae=o.cursor??ae,t(!0),await ne(Math.max(0,4e3-(Date.now()-a)));continue}if(o.archived||o.expired){K={...K,playgroundUrl:o.playground_url??K.playgroundUrl},ze(o.saved,o.archived?"Sai has started another task on this computer since; this one has ended.":"This task\'s details are no longer available (Sai was restarted)."),t(!1);return}ae=o.cursor,K=Fe(K,o),e&&q(K)&&o.saved&&ze({...o.saved,status:K.status}),J(),t(!q(K)),q(K)||await ne(Math.max(0,4e3-(Date.now()-a)))}We()}finally{ye=!1}}function ee(r){G("screen-note").textContent=r,G("screen-note").hidden=!r}var be=()=>!q(K)||Z;async function nt(){for(;be();)await ne(1e3);return"end"}var ke;function me(r="The computer isn\'t running now. Send Sai a task to start it."){Z=!1,ce?ke=r:ee(r),J()}var se=!1,xe=!1;async function _e(){if(ce||!ve)return;ce=!0,se=!1,J();let r=3e3,e=0;try{for(;be()&&!se;){let t=await j.callTool("sai_view_live",{machine_id:ve}).catch(()=>null),a=t&&!t.isError?Ce(t):void 0,s=typeof a?.websocket_url=="string"?a.websocket_url:null;if(!s){if(Ee(K,"no_tunnel")){me();break}ee("Waiting for the computer to start\\u2026"),await ne(8e3);continue}ee("Connecting to the computer\\u2026");let o,c=new Promise(m=>{o=Le(s,G("screen"),{connected:()=>{r=3e3,de=!0,ee(""),J()},lost:(u,h)=>{de=!1,m(h)}})});oe=o;let d=await Promise.race([c,nt()]);if(!be())break;if(Q=o.close(!0)??Q,oe=null,d==="conflict"){se=!0;break}if(d==="blocked"&&++e>=2){ee(pe?"This app keeps the card offline, so the screen can\'t show here. Open the live view link in the chat, or the Playground.":"This app keeps the card offline, so the screen can\'t show here. Watch it in the Playground."),xe=!0;break}if(Ee(K,d)){me();break}if(d==="unreachable"){ee("Waiting for the computer to wake up\\u2026"),await ne(8e3);continue}ee("Reconnecting\\u2026"),await ne(r),r=Math.min(r*2,3e4)}}finally{Q=oe?.close(!0)??Q,oe=null,de=!1,ce=!1,Z=!1,xe||ee(ke??(se?"Being watched somewhere else.":"")),ke=void 0,Q&&q(K)&&We(),J()}}async function Ae(r){let e=K.approval;e&&(K={...K,approval:void 0,status:"running"},J(),await j.callTool("sai_task_approve",{approval_id:e.approvalId,decision:r}).catch(()=>{}),Ie(()=>{}))}j.onToolResult=r=>{let e=Ce(r),t=typeof e?.session_id=="string"?e.session_id:null;!t||t===K.sessionId||(K={...Te,sessionId:t,status:"running"},ae=void 0,ve=typeof e?.machine_id=="string"?e.machine_id:null,he=typeof e?.task_id=="string"?e.task_id:null,pe=typeof e?.watch_url=="string"?e.watch_url:null,J(),Ie(a=>{a&&_e()}))};function Ye(r){r&&(r.theme&&(document.documentElement.dataset.theme=r.theme),r.availableDisplayModes&&(ge=r.availableDisplayModes),r.displayMode&&(te=r.displayMode),J())}j.onHostContext=Ye;async function Re(r){te=await j.requestDisplayMode(r).catch(()=>te),J()}G("pin").onclick=()=>{Re("pip")};G("watch-here").onclick=()=>{_e()};G("use").onclick=()=>{Z=!0,ee(""),J(),Ie(r=>{r?_e():Z&&me()})};G("stop-use").onclick=()=>{Z=!1,J()};G("popout").onclick=()=>pe&&j.openLink(pe);G("expand").onclick=()=>{Re("fullscreen")};G("restore").onclick=()=>{Re("inline")};G("approve").onclick=()=>{Ae("approve")};G("approve-task").onclick=()=>{Ae("approve_for_task")};G("deny").onclick=()=>{Ae("deny")};G("open-approval").onclick=()=>K.approval?.approvalUrl&&j.openLink(K.approval.approvalUrl);G("live").onclick=()=>K.playgroundUrl&&j.openLink(K.playgroundUrl);j.connect("0.6.0").then(r=>{Ve=r.hostInfo?.name??"",Ye(r.hostContext),J()}).catch(()=>J());})();\n\n </script>\n </body>\n</html>\n' : "<!doctype html><html><body><p>Sai task view (build with npm run build)</p></body></html>";
|
|
22698
22783
|
}
|
|
22699
22784
|
function playgroundUrl(apiUrl) {
|
|
22700
22785
|
return /staging/.test(apiUrl) ? "https://staging.platform.simular.cloud/playground" : "https://platform.simular.ai/playground";
|
|
@@ -22930,22 +23015,29 @@ var MAX_TASKS = 50;
|
|
|
22930
23015
|
var TaskLog = class {
|
|
22931
23016
|
tasks = /* @__PURE__ */ new Map();
|
|
22932
23017
|
latest = /* @__PURE__ */ new Map();
|
|
22933
|
-
|
|
22934
|
-
|
|
23018
|
+
latestOnMachine = /* @__PURE__ */ new Map();
|
|
23019
|
+
/** A new task on `sessionId`: it becomes that session's (and machine's) live one. */
|
|
23020
|
+
start(sessionId, machineId2) {
|
|
22935
23021
|
const taskId = randomBytes2(9).toString("base64url");
|
|
22936
|
-
this.tasks.set(taskId, { sessionId });
|
|
23022
|
+
this.tasks.set(taskId, { sessionId, ...machineId2 && { machineId: machineId2 } });
|
|
22937
23023
|
this.latest.set(sessionId, taskId);
|
|
23024
|
+
if (machineId2) this.latestOnMachine.set(machineId2, taskId);
|
|
22938
23025
|
while (this.tasks.size > MAX_TASKS) {
|
|
22939
23026
|
const oldest = this.tasks.keys().next().value;
|
|
22940
23027
|
this.tasks.delete(oldest);
|
|
22941
23028
|
}
|
|
22942
23029
|
return taskId;
|
|
22943
23030
|
}
|
|
22944
|
-
/**
|
|
23031
|
+
/**
|
|
23032
|
+
* `live`: still its session's and machine's newest task; `archived`: a newer
|
|
23033
|
+
* one started on either; `expired`: unknown.
|
|
23034
|
+
*/
|
|
22945
23035
|
state(taskId, sessionId) {
|
|
22946
23036
|
const task = this.tasks.get(taskId);
|
|
22947
23037
|
if (!task || task.sessionId !== sessionId) return "expired";
|
|
22948
|
-
|
|
23038
|
+
if (this.latest.get(sessionId) !== taskId) return "archived";
|
|
23039
|
+
if (task.machineId && this.latestOnMachine.get(task.machineId) !== taskId) return "archived";
|
|
23040
|
+
return "live";
|
|
22949
23041
|
}
|
|
22950
23042
|
saved(taskId) {
|
|
22951
23043
|
return this.tasks.get(taskId)?.saved;
|
|
@@ -23154,7 +23246,7 @@ function createServer2() {
|
|
|
23154
23246
|
},
|
|
23155
23247
|
(args) => run(async () => {
|
|
23156
23248
|
const started = await tools.start(args);
|
|
23157
|
-
const taskId = taskLog.start(started.session_id);
|
|
23249
|
+
const taskId = taskLog.start(started.session_id, started.machine_id);
|
|
23158
23250
|
const watchUrl = await localView?.urlFor(started.session_id, started.machine_id, taskId).catch((err) => {
|
|
23159
23251
|
log(`local view unavailable: ${err instanceof Error ? err.message : String(err)}`);
|
|
23160
23252
|
return void 0;
|
|
@@ -23182,6 +23274,11 @@ function createServer2() {
|
|
|
23182
23274
|
{ description: toolDescriptions.sai_upload, inputSchema: toolSchemas.sai_upload },
|
|
23183
23275
|
(args) => run(() => tools.upload(args))
|
|
23184
23276
|
);
|
|
23277
|
+
mcp.registerTool(
|
|
23278
|
+
"sai_learn",
|
|
23279
|
+
{ description: toolDescriptions.sai_learn, inputSchema: toolSchemas.sai_learn },
|
|
23280
|
+
(args) => run(() => tools.learn(args))
|
|
23281
|
+
);
|
|
23185
23282
|
mcp.registerTool(
|
|
23186
23283
|
"sai_live_link",
|
|
23187
23284
|
{ description: toolDescriptions.sai_live_link, inputSchema: toolSchemas.sai_live_link },
|
package/package.json
CHANGED