From 6c78b12499a5798565c28e423596723c338e5bc3 Mon Sep 17 00:00:00 2001 From: Alexey Fedorov Date: Thu, 24 Sep 2026 01:35:22 -0500 Subject: [PATCH 01/11] docs: spec for Chrome packaged runtime (no remote code) Co-Authored-By: Claude Opus 5.5 --- ...26-09-24-chrome-packaged-runtime-design.md | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 docs/superpowers/specs/2026-09-24-chrome-packaged-runtime-design.md diff --git a/docs/superpowers/specs/2026-09-24-chrome-packaged-runtime-design.md b/docs/superpowers/specs/2026-09-24-chrome-packaged-runtime-design.md new file mode 100644 index 0000000..777f342 --- /dev/null +++ b/docs/superpowers/specs/2026-09-24-chrome-packaged-runtime-design.md @@ -0,0 +1,63 @@ +# Chrome packaged runtime (no remote code) + +Branch: `chrome/packaged-runtime`. Master stays on the P-NP `manifest.json` + `onreset` pipeline so the Edge and Firefox listings keep fast-patching. This branch is the Chrome Web Store build only. + +Background: `../GIZMO_MIGRATION.md` (workspace root). Blue Argon = executing JavaScript that was not in the reviewed package. + +## Goal + +Prodigy loads its own, unmodified `game.min.js`. Every line of JavaScript Play Origin runs ships inside the extension zip. No `fetch` + `eval`, no `onreset`, no prefix/suffix from GitHub. + +Success criteria: + +1. With the dev extension loaded, `math.prodigygame.com` loads the original `game.min.js` from `code.prodigygame.com` (network tab: 200, not blocked). +2. `window._.instance.prodigy`, `_.constants.get("GameConstants.Build.VERSION")`, `_.player`, `_.network` and `_.membership` resolve. +3. With `GameConstants.Debug.EDUCATION_ENABLED` false, a battle question auto-answers through each of the three bypasses (battle `OpenQuestionInterface`, `AnswerQuestion` action, Tower Town). +4. The menu opens, and Shift still toggles it. +5. `grep -rE "eval\(|new Function|onreset|raw\.githubusercontent" extension/build/chrome-mv3-prod` finds nothing written by Play Origin. + +## Why hooks work here + +`game.min.js` is one webpack bundle. Its runtime tags every ESM exports object via `Object.defineProperty(exports, Symbol.toStringTag, {value: "Module"})`. A MAIN-world content script at `document_start` wraps `Object.defineProperty`, keeps a list of those exports objects, and passes everything else straight through. Targets are resolved lazily, after the game boots, by name or shape. Module ids are never used. + +| Old P-NP rule | Packaged replacement | +|---|---| +| `singleton-exposure` | Export that is a class with a static `instance` getter and a `prodigy` prototype getter (module 35120 `q` today). `_.instance` = `q.instance`. | +| `expose-constants` | Export whose `.constants` object has key `"GameConstants.Build.VERSION"` (module 34829 today). Same Map-like `get`/`set`/`has` + `.constants` self-alias as the old suffix. | +| `answer-question-bypass` | Component registry (export object with key `OpenQuestionInterface`, filled by the `EV(name, path)` decorator). Wrap `OpenQuestionInterface.prototype.answerQuestion`. | +| `external-factory-bypass` | Action registry (export object with key `AnswerQuestion`, filled by `ba9(name)`). Wrap `AnswerQuestion.prototype.execute`; bypass calls `this.finish({answerCorrect, responseTime: 0})`. | +| `open-question-bypass` | Exported class whose prototype has `openQuestionInterfaceThenEmitNotifications` (module 82142 `gT` today). Wrap it; bypass calls the callback `(true, 10, 1, false, false, {})`. | +| `safe-bind`, semaphore guard | Dropped. They only guarded against `onreset` running the game twice. | + +Each bypass has the same gate as the old regex: active only when `_.constants.get("GameConstants.Debug.EDUCATION_ENABLED")` is falsy, correct with probability `AUTO_ANSWER_CORRECT_PERCENT` (default 1). Otherwise the original method runs. + +Registry keys are prefab serialization names, so minification can't rename them. Method names were already what the regex rules depended on. + +## Components + +- **`extension/lib/runtime/`**: pure, testable modules. + - `modules.ts`: `defineProperty` hook + the captured-exports list. + - `resolve.ts`: `findSingletonClass`, `findConstants`, `findRegistry(key)`, `findClassWithMethod(name)`, each taking the exports list. + - `bypasses.ts`: the three prototype wraps. Idempotent, marked with a symbol so they never double-wrap. + - `api.ts`: builds the `window._` surface ported from P-NP `wrappers.ts` (`instance`, `constants`, `player`, `network`, `gameData`, `localizer`, `membership`, `hack`, `functions.escapeBattle`, `functions.setMembership`, `__pnp_discoverService`). It re-applies itself when lodash replaces `window._`, same as the old 500 ms poll. When the singleton and constants are resolved, it dispatches `origin:ready` on `window`. +- **`extension/contents/runtime.ts`**: MAIN world, `document_start`, `https://math.prodigygame.com/*`. Installs the hook, then the API and bypasses once resolution succeeds. If a target is still missing after the game boots, it logs `[Origin] hook target missing: ` and continues with what it has (graceful degradation). +- **`extension/contents/menu.ts`**: MAIN world, `document_idle`. Imports the built originGUI bundle so the menu code sits inside the content script. Waits for `origin:ready` before running the menu. +- **originGUI changes** (on this branch only): remove "Update menu", the beta branch loader, the eval console, and the dev socket `eval`. Replace the template-string `eval`s in `player.ts` and `pets.ts` with closures. Data `fetch`es (status message JSON, Prodigy API, asset URLs) stay; they load data, not code. + +## Removed from the Chrome extension + +`background.ts` patch pipeline (the service worker keeps only the DNR image redirects), `contents/prodigy.ts`, `contents/origin-bridge.ts`, `lib/{bundle-cache,manifest,patches,patch-urls}.ts` and their tests, DNR rules 1 (block `game.min.js`) and 2 (strip CSP/XFO; MAIN-world content scripts aren't subject to page CSP), the `raw.githubusercontent.com` host permission, the popup's manifest/menu URL overrides, and the `unlimitedStorage` permission. + +The image redirects to GitHub-hosted PNGs stay. They're images, not code. + +## Testing + +- Unit (node test runner, like the existing tests): run `resolve.ts` and `bypasses.ts` against fixtures that copy the real shapes (a fake exports list with a registry object, a class with a static `instance` getter, and so on). Cover idempotent wrapping, the gate on/off, and a missing-target log. +- No offline run of the real `game.min.js`: it needs a real DOM and a Phaser boot. Live verification covers it. +- Live: `pnpm dev`, load `extension/build/chrome-mv3-dev` unpacked, then walk through success criteria 1–5. + +## Out of scope + +- Firefox and Edge (stay on master). +- P-NP becoming a CI check that loads the latest `game.min.js` and asserts every hook target resolves. That's the next spec once the hooks are proven live. +- Store listing text and version bump. From ff542743831e5038672a8f151b9269702eff9177 Mon Sep 17 00:00:00 2001 From: Alexey Fedorov Date: Thu, 24 Sep 2026 01:44:46 -0500 Subject: [PATCH 02/11] docs: implementation plan for Chrome packaged runtime; spec corrections Co-Authored-By: Claude Opus 5.5 --- .../2026-09-24-chrome-packaged-runtime.md | 1366 +++++++++++++++++ ...26-09-24-chrome-packaged-runtime-design.md | 10 +- 2 files changed, 1372 insertions(+), 4 deletions(-) create mode 100644 docs/superpowers/plans/2026-09-24-chrome-packaged-runtime.md diff --git a/docs/superpowers/plans/2026-09-24-chrome-packaged-runtime.md b/docs/superpowers/plans/2026-09-24-chrome-packaged-runtime.md new file mode 100644 index 0000000..fce4850 --- /dev/null +++ b/docs/superpowers/plans/2026-09-24-chrome-packaged-runtime.md @@ -0,0 +1,1366 @@ +# Chrome Packaged Runtime Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Replace the Chrome extension's fetch-patch-`onreset` pipeline with packaged MAIN-world hooks and a packaged menu, so no JavaScript runs unless it was in the extension zip. + +**Architecture:** A `document_start` MAIN-world content script wraps `Object.defineProperty` to collect webpack export objects while Prodigy's unmodified `game.min.js` loads. After boot it resolves five targets by shape or name (singleton class, constants object, component registry, base action class, Tower Town class). It then wraps three prototype methods for the education bypasses and builds the `window._` API the menu reads. A second MAIN-world content script packages originGUI and starts it on `origin:ready`. + +**Tech Stack:** TypeScript, Plasmo 0.90 (Parcel), node:test with `--experimental-strip-types`, esbuild (originGUI), pnpm. + +**Spec:** `docs/superpowers/specs/2026-09-24-chrome-packaged-runtime-design.md` + +## Global Constraints + +- Branch `chrome/packaged-runtime` only. Never push or merge to master; master stays on the P-NP pipeline for Edge/Firefox. +- Only `extension/` (not `extension/firefox/`) and `originGUI/` change. +- No `eval`, `new Function`, `onreset`, or fetch-then-execute anywhere in code this branch ships. +- pnpm, never npm. No force pushes. +- Log prefix `[Origin]`. +- `lib/runtime/*.ts` modules import only *types* from each other (node's strip-types runner can't resolve extensionless value imports). Value wiring happens in `contents/*.ts`. +- Content script matches: `https://math.prodigygame.com/*`. +- Commits end with `Co-Authored-By: Claude Opus 5.5 `. + +## Review Focus + +1. **Game code reads a webpack getter before its module finishes (TDZ `ReferenceError`)** → the scan skips that value and keeps going (Task 2 test `skips getters that throw`). +2. **Prodigy removes or renames one target** → the other hooks still install, and one `[Origin] hook target missing:` line is logged after the give-up window (Task 2 test `resolves the targets that exist and reports the rest`, Task 5 glue). +3. **The user flips education back on mid-session** → the original method runs again, with no stale bypass (Task 3 tests `runs the original when education is enabled`). +4. **Lodash replaces `window._` after the API is applied** → the API re-applies to the new object without clobbering lodash's own `functions`, and a membership snapshot taken before the swap survives it (Task 4 tests `re-applies after window._ is replaced` and `keeps the original membership snapshot across re-apply`). +5. **Content script evaluated twice, or bypass installer called on every tick** → each method is wrapped exactly once (Task 3 test `wraps once`). + +--- + +### Task 1: Webpack export capture hook + +**Files:** +- Create: `extension/lib/runtime/modules.ts` +- Test: `extension/tests/runtime-modules.test.ts` + +**Interfaces:** +- Produces: `isWebpackExportDescriptor(key: PropertyKey, desc: unknown): boolean`, `installModuleHook(objectCtor: { defineProperty: ObjectConstructor["defineProperty"] }, sink: Set): () => void` (returns uninstall). + +- [ ] **Step 1: Write the failing test** + +```ts +// extension/tests/runtime-modules.test.ts +import { describe, it } from "node:test" +import assert from "node:assert/strict" +import { installModuleHook, isWebpackExportDescriptor } from "../lib/runtime/modules.ts" + +const makeCtor = () => ({ defineProperty: Object.defineProperty }) as { defineProperty: ObjectConstructor["defineProperty"] } + +// Mirrors game.min.js: __webpack_require__.d=(E,w)=>{for(var T in w)o(w,T)&&!o(E,T)&&Object.defineProperty(E,T,{enumerable:!0,get:w[T]})} +const webpackD = (ctor: ReturnType) => (exports: object, definition: Record unknown>) => { + for (const key in definition) { + if (Object.prototype.hasOwnProperty.call(definition, key) && !Object.prototype.hasOwnProperty.call(exports, key)) { + ctor.defineProperty(exports, key, { enumerable: true, get: definition[key] }) + } + } +} + +describe("isWebpackExportDescriptor", () => { + it("accepts webpack's {enumerable, get} export descriptor", () => { + assert.equal(isWebpackExportDescriptor("q", { enumerable: true, get: () => 1 }), true) + }) + it("accepts the Module toStringTag", () => { + assert.equal(isWebpackExportDescriptor(Symbol.toStringTag, { value: "Module" }), true) + }) + it("rejects other descriptors", () => { + assert.equal(isWebpackExportDescriptor("q", { value: 1 }), false) + assert.equal(isWebpackExportDescriptor("q", { enumerable: true, configurable: true, get: () => 1 }), false) + assert.equal(isWebpackExportDescriptor("q", undefined), false) + }) +}) + +describe("installModuleHook", () => { + it("captures export objects defined through the hooked defineProperty", () => { + const ctor = makeCtor() + const sink = new Set() + installModuleHook(ctor, sink) + const exports = {} + webpackD(ctor)(exports, { q: () => 42 }) + assert.ok(sink.has(exports)) + assert.equal((exports as { q: number }).q, 42) + }) + it("passes non-export defines through without capturing", () => { + const ctor = makeCtor() + const sink = new Set() + installModuleHook(ctor, sink) + const obj = {} + ctor.defineProperty(obj, "x", { value: 1, writable: true }) + assert.equal(sink.size, 0) + assert.equal((obj as { x: number }).x, 1) + }) + it("uninstall restores the original", () => { + const ctor = makeCtor() + const uninstall = installModuleHook(ctor, new Set()) + assert.notEqual(ctor.defineProperty, Object.defineProperty) + uninstall() + assert.equal(ctor.defineProperty, Object.defineProperty) + }) +}) +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: `cd extension && node --experimental-strip-types --test tests/runtime-modules.test.ts` +Expected: FAIL, cannot find module `../lib/runtime/modules.ts`. + +- [ ] **Step 3: Write minimal implementation** + +```ts +// extension/lib/runtime/modules.ts +// Captures webpack export objects as Prodigy's unmodified game.min.js creates +// them. webpack's __webpack_require__.d defines every export as +// Object.defineProperty(exports, key, { enumerable: true, get }), and +// __webpack_require__.r tags a few namespaces with Symbol.toStringTag "Module". +// Wrapping Object.defineProperty lets packaged code see those objects without +// rewriting the game's source. + +type DefineProperty = ObjectConstructor["defineProperty"] + +export const isWebpackExportDescriptor = (key: PropertyKey, desc: unknown): boolean => { + if (!desc || typeof desc !== "object") return false + const d = desc as PropertyDescriptor + if (key === Symbol.toStringTag) return d.value === "Module" + return d.enumerable === true && typeof d.get === "function" && Object.keys(d).length === 2 +} + +export const installModuleHook = ( + objectCtor: { defineProperty: DefineProperty }, + sink: Set +): (() => void) => { + const original = objectCtor.defineProperty + const hooked = function defineProperty(target: object, key: PropertyKey, desc: PropertyDescriptor) { + if (isWebpackExportDescriptor(key, desc)) sink.add(target) + return original(target, key, desc) + } as DefineProperty + objectCtor.defineProperty = hooked + return () => { + if (objectCtor.defineProperty === hooked) objectCtor.defineProperty = original + } +} +``` + +- [ ] **Step 4: Run test to verify it passes** + +Run: `cd extension && node --experimental-strip-types --test tests/runtime-modules.test.ts` +Expected: PASS (6 tests). + +- [ ] **Step 5: Commit** + +```bash +git add extension/lib/runtime/modules.ts extension/tests/runtime-modules.test.ts +git commit -m "feat(extension): capture webpack export objects via defineProperty hook" +``` + +--- + +### Task 2: Hook target resolvers + +**Files:** +- Create: `extension/lib/runtime/resolve.ts` +- Test: `extension/tests/runtime-resolve.test.ts` + +**Interfaces:** +- Consumes: nothing at runtime (operates on `Iterable` from Task 1's sink). +- Produces: + - `type AnyClass = Function & { prototype: any }` + - `type Targets = { singletonClass?: AnyClass & { readonly instance?: any }; constants?: Record; componentRegistry?: Record; baseActionClass?: AnyClass; towerTownClass?: AnyClass }` + - `type TargetName = keyof Targets`, `const TARGET_NAMES: readonly TargetName[]` + - `resolveTargets(exportsObjects: Iterable, found: Targets): Targets` (fills only missing targets; returns a new object) + - `missingTargets(t: Targets): TargetName[]` + +- [ ] **Step 1: Write the failing test** + +```ts +// extension/tests/runtime-resolve.test.ts +import { describe, it } from "node:test" +import assert from "node:assert/strict" +import { missingTargets, resolveTargets, TARGET_NAMES } from "../lib/runtime/resolve.ts" + +const exportsOf = (values: Record): object => { + const e = {} + for (const k of Object.keys(values)) Object.defineProperty(e, k, { enumerable: true, get: () => values[k] }) + return e +} + +// Shapes copied from game.min.js (module ids as of 2026.18.1 in comments). +class Singleton { // 35120 q + static _instance: unknown = null + static get instance() { return this._instance } + get game() { return null } + get prodigy() { return null } +} +class GameOnlySingleton { // 61806 W: decoy, has instance+game but no prodigy + static get instance() { return null } + get game() { return null } +} +class ConstantsHolder { // 34829 s + static constants = { "GameConstants.Build.VERSION": "2026.18.1", "GameConstants.Debug.EDUCATION_ENABLED": true } +} +class OpenQuestionInterface { answerQuestion() {} } +const componentRegistry = { OpenQuestionInterface } // 40794 X +class BaseAction { // 62459 rcl + init() {} execute() {} finish() {} findParameter() {} validateParameters() {} +} +class AnswerQuestionAction extends BaseAction { execute() {} } // decoy: owns execute only +class TowerTown { openQuestionInterfaceThenEmitNotifications() {} } // 82142 gT + +const allExports = () => [ + exportsOf({ W: GameOnlySingleton }), + exportsOf({ q: Singleton }), + exportsOf({ A: {}, s: ConstantsHolder }), + exportsOf({ X: componentRegistry, u: class {} }), + exportsOf({ rcl: BaseAction, sub: AnswerQuestionAction }), + exportsOf({ gT: TowerTown }) +] + +describe("resolveTargets", () => { + it("finds every target by shape", () => { + const t = resolveTargets(allExports(), {}) + assert.equal(t.singletonClass, Singleton) + assert.equal(t.constants, ConstantsHolder.constants) + assert.equal(t.componentRegistry, componentRegistry) + assert.equal(t.baseActionClass, BaseAction) + assert.equal(t.towerTownClass, TowerTown) + assert.deepEqual(missingTargets(t), []) + }) + + it("skips getters that throw", () => { + const tdz = {} + Object.defineProperty(tdz, "S", { enumerable: true, get() { throw new ReferenceError("Cannot access 'S' before initialization") } }) + const t = resolveTargets([tdz, ...allExports()], {}) + assert.equal(t.singletonClass, Singleton) + }) + + it("resolves the targets that exist and reports the rest", () => { + const t = resolveTargets([exportsOf({ q: Singleton })], {}) + assert.equal(t.singletonClass, Singleton) + assert.deepEqual(missingTargets(t), TARGET_NAMES.filter((n) => n !== "singletonClass")) + }) + + it("keeps already-found targets and fills the rest later", () => { + const first = resolveTargets([exportsOf({ q: Singleton })], {}) + const second = resolveTargets(allExports(), first) + assert.equal(second.singletonClass, Singleton) + assert.equal(second.towerTownClass, TowerTown) + }) + + it("does not treat a registry that lacks OpenQuestionInterface yet as found", () => { + const t = resolveTargets([exportsOf({ X: {} })], {}) + assert.equal(t.componentRegistry, undefined) + }) +}) +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: `cd extension && node --experimental-strip-types --test tests/runtime-resolve.test.ts` +Expected: FAIL, cannot find module. + +- [ ] **Step 3: Write minimal implementation** + +```ts +// extension/lib/runtime/resolve.ts +// Finds the game objects Play Origin hooks, by shape or by names minification +// can't touch. Uses property descriptors only, so no game getters or methods run +// apart from webpack's own export getters. + +export type AnyClass = Function & { prototype: any } + +export type Targets = { + singletonClass?: AnyClass & { readonly instance?: any } + constants?: Record + componentRegistry?: Record + baseActionClass?: AnyClass + towerTownClass?: AnyClass +} + +export type TargetName = keyof Targets + +export const TARGET_NAMES: readonly TargetName[] = [ + "singletonClass", + "constants", + "componentRegistry", + "baseActionClass", + "towerTownClass" +] + +const BASE_ACTION_METHODS = ["init", "execute", "finish", "findParameter", "validateParameters"] + +const descriptor = (obj: object, key: PropertyKey) => Object.getOwnPropertyDescriptor(obj, key) + +const isClass = (v: unknown): v is AnyClass => + typeof v === "function" && typeof (v as AnyClass).prototype === "object" && (v as AnyClass).prototype !== null + +const ownsMethod = (cls: AnyClass, name: string) => typeof descriptor(cls.prototype, name)?.value === "function" + +// module 35120: class with static `instance` getter whose instances expose `prodigy` +const isSingletonClass = (v: unknown): v is NonNullable => + isClass(v) && typeof descriptor(v, "instance")?.get === "function" && typeof descriptor(v.prototype, "prodigy")?.get === "function" + +// module 34829: `X.constants = {"GameConstants.Build.VERSION": ...}` +const constantsOf = (v: unknown): Record | undefined => { + if (!v || (typeof v !== "object" && typeof v !== "function")) return undefined + const c = descriptor(v, "constants")?.value + return c && typeof c === "object" && Object.prototype.hasOwnProperty.call(c, "GameConstants.Build.VERSION") ? c : undefined +} + +// module 40794 export X, filled by the EV("OpenQuestionInterface", …) decorator +const isComponentRegistry = (v: unknown): v is Record => + !!v && typeof v === "object" && isClass(descriptor(v, "OpenQuestionInterface")?.value) + +// module 62459 export rcl: subclasses only own `validate`/`execute` +const isBaseActionClass = (v: unknown): v is AnyClass => isClass(v) && BASE_ACTION_METHODS.every((m) => ownsMethod(v, m)) + +// module 82142 export gT (Tower Town) +const isTowerTownClass = (v: unknown): v is AnyClass => isClass(v) && ownsMethod(v, "openQuestionInterfaceThenEmitNotifications") + +function* exportValues(exportsObjects: Iterable): Generator { + for (const obj of exportsObjects) { + let keys: string[] + try { + keys = Object.keys(obj) + } catch { + continue + } + for (const key of keys) { + let value: unknown + try { + value = (obj as Record)[key] + } catch { + continue // module still evaluating (TDZ) + } + yield value + } + } +} + +export const missingTargets = (t: Targets): TargetName[] => TARGET_NAMES.filter((n) => !t[n]) + +export const resolveTargets = (exportsObjects: Iterable, found: Targets): Targets => { + const t: Targets = { ...found } + if (missingTargets(t).length === 0) return t + for (const v of exportValues(exportsObjects)) { + if (!t.singletonClass && isSingletonClass(v)) t.singletonClass = v + if (!t.constants) t.constants = constantsOf(v) + if (!t.componentRegistry && isComponentRegistry(v)) t.componentRegistry = v + if (!t.baseActionClass && isBaseActionClass(v)) t.baseActionClass = v + if (!t.towerTownClass && isTowerTownClass(v)) t.towerTownClass = v + if (missingTargets(t).length === 0) break + } + return t +} +``` + +- [ ] **Step 4: Run test to verify it passes** + +Run: `cd extension && node --experimental-strip-types --test tests/runtime-resolve.test.ts` +Expected: PASS (5 tests). + +- [ ] **Step 5: Commit** + +```bash +git add extension/lib/runtime/resolve.ts extension/tests/runtime-resolve.test.ts +git commit -m "feat(extension): resolve hook targets from captured webpack exports" +``` + +--- + +### Task 3: Education bypass wraps + +**Files:** +- Create: `extension/lib/runtime/bypasses.ts` +- Test: `extension/tests/runtime-bypasses.test.ts` + +**Interfaces:** +- Consumes: `AnyClass` type from `resolve.ts` (type-only import). +- Produces: + - `type GetConstants = () => Record | undefined` + - `installOpenQuestionBypass(cls: AnyClass, getConstants: GetConstants, random?: () => number): boolean` + - `installAnswerQuestionActionBypass(baseActionClass: AnyClass, getConstants: GetConstants, random?: () => number): boolean` + - `installTowerTownBypass(cls: AnyClass, getConstants: GetConstants): boolean` + - All return `true` if the wrap is (or already was) installed, `false` if the method is missing. + +Gate semantics (copied from the P-NP regex replacements): bypass active iff constants exist and `constants["GameConstants.Debug.EDUCATION_ENABLED"]` is falsy. Correct iff `random() < (constants["GameConstants.Debug.AUTO_ANSWER_CORRECT_PERCENT"] || 1)`. + +- [ ] **Step 1: Write the failing test** + +```ts +// extension/tests/runtime-bypasses.test.ts +import { describe, it } from "node:test" +import assert from "node:assert/strict" +import { + installAnswerQuestionActionBypass, + installOpenQuestionBypass, + installTowerTownBypass +} from "../lib/runtime/bypasses.ts" + +const EDU = "GameConstants.Debug.EDUCATION_ENABLED" +const PCT = "GameConstants.Debug.AUTO_ANSWER_CORRECT_PERCENT" + +const signal = () => { + const calls: unknown[][] = [] + return { calls, dispatch: (...args: unknown[]) => { calls.push(args) } } +} + +const makeOpenQuestionClass = () => + class OpenQuestionInterface { + onQuestionAnswered = signal() + onQuestionAnsweredCorrectly = signal() + onQuestionAnsweredIncorrectly = signal() + opened = 0 + answerQuestion() { this.opened++ } + } + +describe("installOpenQuestionBypass", () => { + it("runs the original when education is enabled", () => { + const C = makeOpenQuestionClass() + const constants: Record = { [EDU]: true, [PCT]: 1 } + installOpenQuestionBypass(C, () => constants) + const q = new C() + q.answerQuestion() + assert.equal(q.opened, 1) + assert.equal(q.onQuestionAnswered.calls.length, 0) + }) + + it("answers correctly without opening when education is disabled", () => { + const C = makeOpenQuestionClass() + installOpenQuestionBypass(C, () => ({ [EDU]: false, [PCT]: 1 }), () => 0) + const q = new C() + q.answerQuestion() + assert.equal(q.opened, 0) + assert.deepEqual(q.onQuestionAnswered.calls, [[true, 0, null]]) + assert.deepEqual(q.onQuestionAnsweredCorrectly.calls, [[0, null]]) + assert.equal(q.onQuestionAnsweredIncorrectly.calls.length, 0) + }) + + it("answers incorrectly when the roll misses the percentage", () => { + const C = makeOpenQuestionClass() + installOpenQuestionBypass(C, () => ({ [EDU]: false, [PCT]: 0.5 }), () => 0.9) + const q = new C() + q.answerQuestion() + assert.deepEqual(q.onQuestionAnswered.calls, [[false, 0, null]]) + assert.deepEqual(q.onQuestionAnsweredIncorrectly.calls, [[0, null]]) + }) + + it("follows the flag live: bypass off again once education is re-enabled", () => { + const C = makeOpenQuestionClass() + const constants: Record = { [EDU]: false } + installOpenQuestionBypass(C, () => constants, () => 0) + const q = new C() + q.answerQuestion() + constants[EDU] = true + q.answerQuestion() + assert.equal(q.opened, 1) + }) + + it("runs the original while constants are unresolved", () => { + const C = makeOpenQuestionClass() + installOpenQuestionBypass(C, () => undefined) + const q = new C() + q.answerQuestion() + assert.equal(q.opened, 1) + }) + + it("wraps once", () => { + const C = makeOpenQuestionClass() + installOpenQuestionBypass(C, () => undefined) + const first = C.prototype.answerQuestion + assert.equal(installOpenQuestionBypass(C, () => undefined), true) + assert.equal(C.prototype.answerQuestion, first) + }) + + it("returns false when the method is missing", () => { + assert.equal(installOpenQuestionBypass(class {}, () => undefined), false) + }) +}) + +describe("installAnswerQuestionActionBypass", () => { + const make = () => { + class BaseAction { + data: any = null + finished: unknown = undefined + init(data: any) { this.data = data } + execute() {} + finish(result: unknown) { this.finished = result } + findParameter() { return null } + validateParameters() { return true } + } + class AnswerQuestion extends BaseAction { executed = false; execute() { this.executed = true } } + class Other extends BaseAction { executed = false; execute() { this.executed = true } } + return { BaseAction, AnswerQuestion, Other } + } + + it("finishes AnswerQuestion actions without asking when education is disabled", () => { + const { BaseAction, AnswerQuestion } = make() + installAnswerQuestionActionBypass(BaseAction, () => ({ [EDU]: false }), () => 0) + const a = new AnswerQuestion() + a.init({ Type: "AnswerQuestion" }) + a.execute() + assert.equal(a.executed, false) + assert.deepEqual(a.finished, { answerCorrect: true, responseTime: 0 }) + }) + + it("runs the original AnswerQuestion when education is enabled", () => { + const { BaseAction, AnswerQuestion } = make() + installAnswerQuestionActionBypass(BaseAction, () => ({ [EDU]: true })) + const a = new AnswerQuestion() + a.init({ Type: "AnswerQuestion" }) + a.execute() + assert.equal(a.executed, true) + }) + + it("leaves other actions and the base execute alone", () => { + const { BaseAction, Other } = make() + const baseExecute = BaseAction.prototype.execute + installAnswerQuestionActionBypass(BaseAction, () => ({ [EDU]: false })) + const o = new Other() + o.init({ Type: "Other" }) + o.execute() + assert.equal(o.executed, true) + assert.equal(BaseAction.prototype.execute, baseExecute) + }) +}) + +describe("installTowerTownBypass", () => { + class TowerTown { + opened = 0 + openQuestionInterfaceThenEmitNotifications(_e: unknown, _w: unknown, _t: unknown, _s: unknown, _cb?: Function) { this.opened++ } + } + + it("calls the completion callback as a correct answer", () => { + installTowerTownBypass(TowerTown, () => ({ [EDU]: false })) + const t = new TowerTown() + const calls: unknown[][] = [] + t.openQuestionInterfaceThenEmitNotifications(1, true, null, false, (...a: unknown[]) => calls.push(a)) + assert.equal(t.opened, 0) + assert.deepEqual(calls, [[true, 10, 1, false, false, {}]]) + }) + + it("tolerates a missing callback", () => { + installTowerTownBypass(TowerTown, () => ({ [EDU]: false })) + assert.doesNotThrow(() => new TowerTown().openQuestionInterfaceThenEmitNotifications(1, true, null, false)) + }) +}) +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: `cd extension && node --experimental-strip-types --test tests/runtime-bypasses.test.ts` +Expected: FAIL, cannot find module. + +- [ ] **Step 3: Write minimal implementation** + +```ts +// extension/lib/runtime/bypasses.ts +// Education bypasses, as prototype wraps. Replaces the P-NP regex rules +// answer-question-bypass, external-factory-bypass and open-question-bypass, +// which injected the same early returns into game.min.js source. + +import type { AnyClass } from "./resolve" + +export type GetConstants = () => Record | undefined + +const EDUCATION_ENABLED = "GameConstants.Debug.EDUCATION_ENABLED" +const CORRECT_PERCENT = "GameConstants.Debug.AUTO_ANSWER_CORRECT_PERCENT" +const WRAPPED = Symbol.for("playOrigin.wrapped") + +type AnyFn = (...args: any[]) => any + +const bypassed = (c: Record | undefined): c is Record => !!c && !c[EDUCATION_ENABLED] + +const rollCorrect = (c: Record, random: () => number) => + random() < ((c[CORRECT_PERCENT] as number) || 1) + +// Wraps an *own* prototype method once. Returns false if there is none. +const wrapOwnMethod = (proto: any, name: string, make: (original: AnyFn) => AnyFn): boolean => { + const original = Object.getOwnPropertyDescriptor(proto, name)?.value + if (typeof original !== "function") return false + if ((original as any)[WRAPPED]) return true + const wrapped = make(original) + ;(wrapped as any)[WRAPPED] = true + proto[name] = wrapped + return true +} + +export const installOpenQuestionBypass = ( + cls: AnyClass, + getConstants: GetConstants, + random: () => number = Math.random +): boolean => + wrapOwnMethod(cls.prototype, "answerQuestion", (original) => + function (this: any, ...args: unknown[]) { + const c = getConstants() + if (!bypassed(c)) return original.apply(this, args) + const correct = rollCorrect(c, random) + this.onQuestionAnswered.dispatch(correct, 0, null) + if (correct) this.onQuestionAnsweredCorrectly.dispatch(0, null) + else this.onQuestionAnsweredIncorrectly.dispatch(0, null) + } + ) + +// The action registry is module-private, so catch AnswerQuestion when the +// action factory calls init(data) with data.Type === "AnswerQuestion". +export const installAnswerQuestionActionBypass = ( + baseActionClass: AnyClass, + getConstants: GetConstants, + random: () => number = Math.random +): boolean => + wrapOwnMethod(baseActionClass.prototype, "init", (originalInit) => + function (this: any, ...args: unknown[]) { + const result = originalInit.apply(this, args) + const data = args[0] as { Type?: unknown } | null | undefined + const proto = Object.getPrototypeOf(this) + if (data?.Type === "AnswerQuestion" && proto !== baseActionClass.prototype) { + wrapOwnMethod(proto, "execute", (originalExecute) => + function (this: any, ...executeArgs: unknown[]) { + const c = getConstants() + if (!bypassed(c)) return originalExecute.apply(this, executeArgs) + this.finish({ answerCorrect: rollCorrect(c, random), responseTime: 0 }) + } + ) + } + return result + } + ) + +export const installTowerTownBypass = (cls: AnyClass, getConstants: GetConstants): boolean => + wrapOwnMethod(cls.prototype, "openQuestionInterfaceThenEmitNotifications", (original) => + function (this: any, ...args: unknown[]) { + if (!bypassed(getConstants())) return original.apply(this, args) + const done = args[4] + if (typeof done === "function") done(true, 10, 1, false, false, {}) + } + ) +``` + +- [ ] **Step 4: Run test to verify it passes** + +Run: `cd extension && node --experimental-strip-types --test tests/runtime-bypasses.test.ts` +Expected: PASS (12 tests). + +- [ ] **Step 5: Commit** + +```bash +git add extension/lib/runtime/bypasses.ts extension/tests/runtime-bypasses.test.ts +git commit -m "feat(extension): packaged education bypasses as prototype wraps" +``` + +--- + +### Task 4: `window._` API and ready signal + +**Files:** +- Create: `extension/lib/runtime/api.ts`, `extension/lib/runtime/ready.ts` +- Test: `extension/tests/runtime-api.test.ts` + +**Interfaces:** +- Consumes: `Targets` type from `resolve.ts` (type-only). +- Produces: + - `api.ts`: `discoverService(gc: any, matches: (inst: any) => boolean): any`, `addConstantsApi(raw: Record): Record`, `createOriginApi(deps: { singletonClass: NonNullable; constants: Record }): { ensure(win: any): void; isReady(win: any): boolean }` + - `ready.ts`: `READY_EVENT = "origin:ready"`, `markOriginReady(win: any): void`, `whenOriginReady(win: any): Promise` + +- [ ] **Step 1: Write the failing test** + +```ts +// extension/tests/runtime-api.test.ts +import { describe, it } from "node:test" +import assert from "node:assert/strict" +import { addConstantsApi, createOriginApi, discoverService } from "../lib/runtime/api.ts" +import { markOriginReady, READY_EVENT, whenOriginReady } from "../lib/runtime/ready.ts" + +const makeGame = () => { + const player = { data: { name: "x" }, appearanceChanged: false, unlockMemberItems() { this.unlocked = true }, unlocked: false } + const membership = { _data: { active: false }, isMember: false, hasFeatureAccess() { return false }, updateMembershipDates() {} } + const network = { getCharData() {}, processPlayer: 1, sendZoneEvent() {} } + const services = new Map([ + ["NotAnId", { player: { data: {} } }], + ["1a2-3b4c", { player }], + ["83f-419b", membership], + ["ab-cd", network] + ]) + const gameContainer = { _inversifyContainer: { _bindingDictionary: { _map: services } }, get: (id: unknown) => services.get(id) } + const singleton = { prodigy: { gameContainer } as any, game: { state: { states: new Map([["Boot", { _gameData: { pet: [] } }]]) } } } + class Singleton { static get instance() { return singleton } get prodigy() { return null } } + const constants: Record = { "GameConstants.Build.VERSION": "2026.18.1" } + return { player, membership, network, gameContainer, singleton, Singleton, constants } +} + +describe("discoverService", () => { + it("returns the first hex-id binding matching the shape", () => { + const g = makeGame() + // "NotAnId" also has a player but is not a hex service id, so it is skipped. + assert.equal(discoverService(g.gameContainer, (i) => "player" in i), g.gameContainer.get("1a2-3b4c")) + }) + it("returns null without a binding map", () => { + assert.equal(discoverService({}, () => true), null) + }) +}) + +describe("addConstantsApi", () => { + it("adds hidden Map-like accessors over the same object", () => { + const raw: Record = { "GameConstants.Debug.EDUCATION_ENABLED": true } + addConstantsApi(raw) + raw.set("GameConstants.Debug.EDUCATION_ENABLED", false) + assert.equal(raw["GameConstants.Debug.EDUCATION_ENABLED"], false) + assert.equal(raw.get("GameConstants.Debug.EDUCATION_ENABLED"), false) + assert.equal(raw.has("GameConstants.Debug.EDUCATION_ENABLED"), true) + assert.equal(raw.constants, raw) + assert.deepEqual(Object.keys(raw), ["GameConstants.Debug.EDUCATION_ENABLED"]) + }) +}) + +describe("createOriginApi", () => { + it("creates window._ and exposes instance, constants, player, network, gameData, membership", () => { + const g = makeGame() + const win: any = {} + createOriginApi({ singletonClass: g.Singleton, constants: g.constants }).ensure(win) + assert.equal(win._.instance, g.singleton) + assert.equal(win._.constants, g.constants) + assert.equal(win._.player, g.player) + assert.equal(win._.network, g.network) + assert.equal(win._.network.game, g.singleton.game) + assert.deepEqual(win._.gameData, { pet: [] }) + assert.equal(win._.membership, g.membership) + }) + + it("re-applies after window._ is replaced and keeps lodash's functions", () => { + const g = makeGame() + const win: any = {} + const api = createOriginApi({ singletonClass: g.Singleton, constants: g.constants }) + api.ensure(win) + const lodashFunctions = () => [] + const lodash: any = Object.assign(function lodash() {}, { functions: lodashFunctions, cloneDeep: (x: unknown) => x }) + win._ = lodash + api.ensure(win) + assert.equal(win._, lodash) + assert.equal(win._.instance, g.singleton) + assert.equal(win._.functions, lodashFunctions) + assert.equal(typeof win._.functions.setMembership, "function") + }) + + it("setMembership toggles and restores the original membership data", () => { + const g = makeGame() + const win: any = {} + createOriginApi({ singletonClass: g.Singleton, constants: g.constants }).ensure(win) + const original = g.membership._data + assert.equal(win._.functions.setMembership(true), true) + assert.equal((g.membership._data as any).active, true) + assert.equal(g.membership.hasFeatureAccess(), true) + assert.equal(g.player.unlocked, true) + assert.equal(win._.functions.setMembership(false), true) + assert.equal(g.membership._data, original) + assert.equal(g.membership.hasFeatureAccess(), false) + }) + + it("keeps the original membership snapshot across re-apply", () => { + const g = makeGame() + const win: any = {} + const api = createOriginApi({ singletonClass: g.Singleton, constants: g.constants }) + api.ensure(win) + const original = g.membership._data + win._.functions.setMembership(true) + win._ = Object.assign(function lodash() {}, { functions: () => [] }) + api.ensure(win) + win._.functions.setMembership(false) + assert.equal(g.membership._data, original) + }) + + it("isReady waits for prodigy and player", () => { + const g = makeGame() + const win: any = {} + const api = createOriginApi({ singletonClass: g.Singleton, constants: g.constants }) + const prodigy = g.singleton.prodigy + g.singleton.prodigy = null + api.ensure(win) + assert.equal(api.isReady(win), false) + g.singleton.prodigy = prodigy + assert.equal(api.isReady(win), true) + }) +}) + +describe("ready signal", () => { + it("resolves listeners registered before and after the signal", async () => { + const win: any = new EventTarget() + const early = whenOriginReady(win) + let events = 0 + win.addEventListener(READY_EVENT, () => events++) + markOriginReady(win) + markOriginReady(win) + await early + await whenOriginReady(win) + assert.equal(events, 1) + }) +}) +``` + +- [ ] **Step 2: Run test to verify it fails** + +Run: `cd extension && node --experimental-strip-types --test tests/runtime-api.test.ts` +Expected: FAIL, cannot find module. + +- [ ] **Step 3: Write minimal implementation** + +```ts +// extension/lib/runtime/ready.ts +// Tells the packaged menu the game is ready to be modded. + +export const READY_EVENT = "origin:ready" +const READY_FLAG = "__ORIGIN_READY__" + +export const markOriginReady = (win: any): void => { + if (win[READY_FLAG]) return + win[READY_FLAG] = true + win.dispatchEvent(new Event(READY_EVENT)) +} + +export const whenOriginReady = (win: any): Promise => + win[READY_FLAG] + ? Promise.resolve() + : new Promise((resolve) => win.addEventListener(READY_EVENT, () => resolve(), { once: true })) +``` + +```ts +// extension/lib/runtime/api.ts +// The `window._` surface originGUI reads. Ported from the old P-NP suffix +// (P-NP/src/wrappers.ts), minus the parts that only existed because the +// patched bundle ran twice. + +import type { Targets } from "./resolve" + +type OriginApiDeps = { + singletonClass: NonNullable + constants: Record +} + +const API_MARK = "__originApi" +const SERVICE_ID = /^[0-9a-f]{2,4}-[0-9a-f]{2,6}$/ + +const defineHidden = (target: object, key: PropertyKey, value: unknown) => + Object.defineProperty(target, key, { value, configurable: true, writable: true }) + +const defineGetter = (target: object, key: PropertyKey, get: () => unknown) => + Object.defineProperty(target, key, { get, configurable: true, enumerable: true }) + +// Service ids drift every build; enumerate Inversify bindings and match by shape. +export const discoverService = (gc: any, matches: (inst: any) => boolean): any => { + let map: Map | undefined + try { + map = gc._inversifyContainer._bindingDictionary._map + } catch { + return null + } + if (!map || typeof map.keys !== "function") return null + for (const id of map.keys()) { + if (typeof id !== "string" || !SERVICE_ID.test(id)) continue + try { + const inst = gc.get(id) + if (inst && matches(inst)) return inst + } catch {} + } + return null +} + +// The menu writes `_.constants.constants[key]` and reads `_.constants.get(key)`; +// both must hit the object the game itself reads. +export const addConstantsApi = (raw: Record): Record => { + if (typeof raw.get !== "function") { + defineHidden(raw, "get", (key: string) => raw[key]) + defineHidden(raw, "set", (key: string, value: unknown) => { + raw[key] = value + return raw + }) + defineHidden(raw, "has", (key: string) => key in raw) + defineHidden(raw, "constants", raw) + } + return raw +} + +const isPlayerService = (inst: any) => { + try { + const p = inst.player + return !!p && typeof p === "object" && "data" in p + } catch { + return false + } +} +const isNetworkManager = (inst: any) => + typeof inst.getCharData === "function" && "processPlayer" in inst && typeof inst.sendZoneEvent === "function" +const isMembershipService = (inst: any) => typeof inst.hasFeatureAccess === "function" && "isMember" in inst + +export const createOriginApi = (deps: OriginApiDeps) => { + const services: { player?: any; network?: any; membership?: any } = {} + let membershipOriginal: { data: unknown } | undefined + + const instance = () => deps.singletonClass.instance ?? null + const find = (key: keyof typeof services, matches: (inst: any) => boolean) => { + if (services[key]) return services[key] + const gc = instance()?.prodigy?.gameContainer + if (!gc) return null + const svc = discoverService(gc, matches) + if (svc) services[key] = svc + return svc + } + + const apply = (target: any) => { + defineGetter(target, "instance", instance) + Object.defineProperty(target, "constants", { + value: addConstantsApi(deps.constants), + configurable: true, + enumerable: true, + writable: true + }) + // The service caches the player; `.player` is a getter returning a fresh object. + defineGetter(target, "player", () => find("player", isPlayerService)?.player ?? null) + defineGetter(target, "gameData", () => { + try { + return instance()?.game?.state?.states?.get?.("Boot")?._gameData ?? null + } catch { + return null + } + }) + defineGetter(target, "network", () => { + const nm = find("network", isNetworkManager) + if (nm && !nm.game) { + try { + defineGetter(nm, "game", () => instance()?.game ?? null) + } catch {} + } + return nm + }) + defineGetter(target, "membership", () => find("membership", isMembershipService)) + + const setMembership = (active: boolean): boolean => { + const ms = find("membership", isMembershipService) + if (!ms) return false + if (!membershipOriginal) membershipOriginal = { data: ms._data } + if (active) { + const day = 86_400_000 + ms._data = { + active: true, + features: [], + membershipStartTs: new Date(Date.now() - day).toISOString(), + membershipEndTs: new Date(Date.now() + 10 * 365 * day).toISOString() + } + // memberTier derives from hasFeatureAccess, so this promotes to Ultra. + defineHidden(ms, "hasFeatureAccess", () => true) + try { ms.updateMembershipDates?.() } catch {} + try { target.player?.unlockMemberItems?.() } catch {} + } else { + ms._data = membershipOriginal.data + if (Object.getOwnPropertyDescriptor(ms, "hasFeatureAccess")) delete ms.hasFeatureAccess + try { ms.updateMembershipDates?.() } catch {} + } + try { + const p = target.player + if (p) p.appearanceChanged = true + } catch {} + return true + } + // lodash owns `_.functions`; hang ours off it instead of replacing it. + if (target.functions == null) target.functions = Object.create(null) + defineHidden(target.functions, "setMembership", setMembership) + + defineHidden(target, API_MARK, true) + } + + return { + ensure(win: any): void { + if (win._ == null) win._ = {} + if (!win._[API_MARK]) apply(win._) + }, + isReady(win: any): boolean { + try { + return !!(instance()?.prodigy && win._?.player) + } catch { + return false + } + } + } +} +``` + +- [ ] **Step 4: Run test to verify it passes** + +Run: `cd extension && node --experimental-strip-types --test tests/runtime-api.test.ts` +Expected: PASS (9 tests). + +- [ ] **Step 5: Commit** + +```bash +git add extension/lib/runtime/api.ts extension/lib/runtime/ready.ts extension/tests/runtime-api.test.ts +git commit -m "feat(extension): packaged window._ API and origin:ready signal" +``` + +--- + +### Task 5: Runtime content script; retire the onreset injection (LIVE CHECKPOINT A) + +**Files:** +- Create: `extension/contents/runtime.ts` +- Delete: `extension/contents/prodigy.ts`, `extension/contents/origin-bridge.ts` +- Replace: `extension/background.ts` (image redirects only) + +**Interfaces:** +- Consumes: everything from Tasks 1–4. +- Produces: page globals `window._` (API) and `window.__ORIGIN_READY__`, and the `origin:ready` event. + +- [ ] **Step 1: Write `extension/contents/runtime.ts`** + +```ts +import type { PlasmoCSConfig } from "plasmo" +import { createOriginApi } from "../lib/runtime/api" +import { + installAnswerQuestionActionBypass, + installOpenQuestionBypass, + installTowerTownBypass +} from "../lib/runtime/bypasses" +import { installModuleHook } from "../lib/runtime/modules" +import { markOriginReady } from "../lib/runtime/ready" +import { missingTargets, resolveTargets, type Targets } from "../lib/runtime/resolve" +import { VERSION } from "../lib/version" + +export const config: PlasmoCSConfig = { + matches: ["https://math.prodigygame.com/*"], + run_at: "document_start", + world: "MAIN" +} + +// Must run before game.min.js so every webpack export object is seen. +const exportsObjects = new Set() +installModuleHook(Object, exportsObjects) + +const TICK_MS = 500 +const GIVE_UP_MS = 120_000 +const startedAt = Date.now() + +let targets: Targets = {} +let api: ReturnType | undefined +let reportedMissing = false +const installed = new Set() +const getConstants = () => targets.constants + +const install = (name: string, run: () => boolean) => { + if (installed.has(name)) return + if (run()) { + installed.add(name) + console.log(`[Origin] hook installed: ${name}`) + } +} + +const tick = () => { + const searching = missingTargets(targets).length > 0 && Date.now() - startedAt < GIVE_UP_MS + if (searching) targets = resolveTargets(exportsObjects, targets) + + const { componentRegistry, baseActionClass, towerTownClass, singletonClass, constants } = targets + if (componentRegistry?.OpenQuestionInterface) { + install("OpenQuestionInterface.answerQuestion", () => + installOpenQuestionBypass(componentRegistry.OpenQuestionInterface, getConstants)) + } + if (baseActionClass) install("AnswerQuestion action", () => installAnswerQuestionActionBypass(baseActionClass, getConstants)) + if (towerTownClass) install("Tower Town questions", () => installTowerTownBypass(towerTownClass, getConstants)) + + if (singletonClass && constants) { + api ??= createOriginApi({ singletonClass, constants }) + api.ensure(window) + if (api.isReady(window)) markOriginReady(window) + } + + if (!searching && !reportedMissing) { + const missing = missingTargets(targets) + if (missing.length > 0) { + reportedMissing = true + console.warn(`[Origin] hook target missing: ${missing.join(", ")}`) + } + } +} + +setInterval(() => { + try { + tick() + } catch (e) { + console.error("[Origin] runtime tick failed:", e) + } +}, TICK_MS) + +console.log(`[Origin] packaged runtime active v${VERSION}`) +``` + +- [ ] **Step 2: Delete the old injection scripts** + +```bash +git rm extension/contents/prodigy.ts extension/contents/origin-bridge.ts +``` + +- [ ] **Step 3: Replace `extension/background.ts`** + +```ts +// Background service worker for Play Origin (Chrome Web Store build). +// +// Only job: register the DNR rules that swap Prodigy's login background and +// logo for Play Origin art. No script blocking, no header stripping, and no +// code fetching; the game runs its own game.min.js. + +const RULES: chrome.declarativeNetRequest.Rule[] = [ + { + id: 3, + priority: 2, + action: { + type: chrome.declarativeNetRequest.RuleActionType.REDIRECT, + redirect: { url: "https://raw.githubusercontent.com/ProdigyPXP/ProdigyOrigin/master/.github/origin-bg.png" } + }, + condition: { + urlFilter: "*://cdn.prodigygame.com/game/assets/v1_cache/single-images/login-bg-13/1/login-bg-13.png", + resourceTypes: [ + chrome.declarativeNetRequest.ResourceType.MAIN_FRAME, + chrome.declarativeNetRequest.ResourceType.SUB_FRAME, + chrome.declarativeNetRequest.ResourceType.IMAGE, + chrome.declarativeNetRequest.ResourceType.OTHER + ] + } + }, + { + id: 4, + priority: 2, + action: { + type: chrome.declarativeNetRequest.RuleActionType.REDIRECT, + redirect: { url: "https://raw.githubusercontent.com/ProdigyPXP/ProdigyOrigin/master/.github/origin-logo.png" } + }, + condition: { + urlFilter: "*://code.prodigygame.com/assets/svg/*logo*-*.svg", + resourceTypes: [ + chrome.declarativeNetRequest.ResourceType.MAIN_FRAME, + chrome.declarativeNetRequest.ResourceType.SUB_FRAME, + chrome.declarativeNetRequest.ResourceType.IMAGE, + chrome.declarativeNetRequest.ResourceType.OTHER + ] + } + } +] + +chrome.runtime.onInstalled.addListener(async () => { + const existing = await chrome.declarativeNetRequest.getDynamicRules() + await chrome.declarativeNetRequest.updateDynamicRules({ + removeRuleIds: existing.map((r) => r.id), + addRules: RULES + }) + console.log("[Origin] DeclarativeNetRequest rules registered successfully") +}) +``` + +`onInstalled` clears the old block and CSP-strip rules (ids 1, 2) that a previous install left behind. + +- [ ] **Step 4: Unit tests still pass, typecheck, dev build** + +Run: `cd extension && pnpm test && pnpm typecheck` +Expected: every `runtime-*` test passes. Old pipeline tests (`patches`, `manifest`, `bundle-cache`, `patch-urls`, `integration`) still pass because their lib files still exist; Task 7 deletes them. + +Run: `cd extension && pnpm dev` (background). Expected: Plasmo prints the `build/chrome-mv3-dev` output with no errors. + +- [ ] **Step 5: LIVE CHECKPOINT A (user)** + +The user loads `extension/build/chrome-mv3-dev` unpacked. If the production Play Origin extension is installed, the user disables it first. Then they open `https://math.prodigygame.com/` and log in. Verify: +1. Network: `code.prodigygame.com/code/*/game.min.js` returns 200, not blocked. +2. Console shows `[Origin] packaged runtime active`, three `[Origin] hook installed:` lines, and no `hook target missing`. +3. In the console: `_.instance.prodigy`, `_.constants.get("GameConstants.Build.VERSION")`, `_.player.data`, `_.network` and `_.membership` are all non-null. `__ORIGIN_READY__ === true`. +4. `_.constants.set("GameConstants.Debug.EDUCATION_ENABLED", false)`, then enter a battle and attack: no question appears and the attack goes through. + +If any check fails, debug with systematic-debugging before Task 6. + +- [ ] **Step 6: Commit** + +```bash +git add extension/contents/runtime.ts extension/background.ts +git commit -m "feat(extension): load Prodigy's own game.min.js with packaged runtime hooks + +Removes the onreset injection, bridge, game.min.js block and CSP strip." +``` + +--- + +### Task 6: Package the menu (LIVE CHECKPOINT B) + +**Files:** +- Modify: `originGUI/build.mjs` (emit `dist/menu.js` + `dist/menu.d.ts`) +- Modify: `originGUI/src/index.ts` (drop dev socket eval and socket.io import) +- Modify: `originGUI/src/hacks/utility.ts` (drop "Update menu" and "Eval Console") +- Modify: `originGUI/src/hacks/beta.ts` (drop "Switch Branch") +- Modify: `originGUI/src/hacks/player.ts:422`, `originGUI/src/hacks/pets.ts:170` (closures instead of eval) +- Modify: `.gitignore`, `extension/package.json` scripts +- Create: `extension/contents/menu.ts` +- Rebuild + commit: `originGUI/dist/bundle.js` + +**Interfaces:** +- Consumes: `whenOriginReady` from `lib/runtime/ready.ts`. +- Produces: `originGUI/dist/menu.js` with `export default function startOriginMenu(): void`. + +- [ ] **Step 1: Remove remote/dynamic code paths from originGUI** + +In `originGUI/src/index.ts`: delete the line `import { io } from "socket.io-client"; // Import socket.io-client` and the whole `if (process.env.NODE_ENV === "development") { const socket = io(...) ... eval(data); ... }` block. + +In `originGUI/src/hacks/utility.ts`: delete everything from `// Begin Update menu` through `// End Update menu`, and from `// Begin Eval Console` through `// End Eval Console`. + +In `originGUI/src/hacks/beta.ts`: delete from `// Begin Switch Branch` through the closing `});` of that `new Hack(category.beta, "Switch Branch", ...)` call (it ends with `return await eval(await (await fetch(...)).text());\n});`), including an `// End Switch Branch` marker if present. + +In `originGUI/src/hacks/player.ts` replace +```ts + eval(`player.getLevel = () => {return ${level.value}}`); +``` +with +```ts + player.getLevel = () => Number(level.value); +``` + +In `originGUI/src/hacks/pets.ts` replace +```ts + // sorry in advance + eval(`player.kennel.petTeam[parseInt(${pet.value})+1].getLevel = () => {return ${num}}`); +``` +with +```ts + player.kennel.petTeam[parseInt(pet.value) + 1].getLevel = () => Number(num); +``` + +Verify: `grep -rnE "eval\(|new Function|socket\.io|raw\.githubusercontent.*bundle" originGUI/src` prints nothing. + +- [ ] **Step 2: Emit the menu module from `originGUI/build.mjs`** + +Below `const bundlePath = ...` add: +```js +const menuModulePath = path.join(distDir, "menu.js"); +const menuTypesPath = path.join(distDir, "menu.d.ts"); +``` +Below `createScssPlugin` add: +```js +// Wraps the IIFE bundle in a function so the Chrome extension can package the +// menu inside a content script and start it once the game is ready. +async function writeMenuModule () { + const bundle = await fs.promises.readFile(bundlePath, "utf8"); + await fs.promises.writeFile(menuModulePath, `// Generated by originGUI/build.mjs. Do not edit.\nexport default function startOriginMenu () {\n${bundle}\n}\n`); + await fs.promises.writeFile(menuTypesPath, "export default function startOriginMenu (): void;\n"); +} +``` +At the end of `buildBundle`, after `await esbuild.build({...});`, add `await writeMenuModule();`. + +Append to `.gitignore`: +``` +# Generated menu module for the Chrome extension +originGUI/dist/menu.js +originGUI/dist/menu.d.ts +``` + +- [ ] **Step 3: Menu content script** + +```ts +// extension/contents/menu.ts +import type { PlasmoCSConfig } from "plasmo" +import startOriginMenu from "../../originGUI/dist/menu.js" +import { whenOriginReady } from "../lib/runtime/ready" + +export const config: PlasmoCSConfig = { + matches: ["https://math.prodigygame.com/*"], + run_at: "document_idle", + world: "MAIN" +} + +// originGUI reads window._.player at load, so start only once the game is ready. +whenOriginReady(window).then(() => { + try { + startOriginMenu() + console.log("[Origin] menu started") + } catch (e) { + console.error("[Origin] menu failed to start:", e) + } +}) +``` + +- [ ] **Step 4: Build originGUI before the extension** + +In `extension/package.json` `scripts`: +```json +"menu": "pnpm --dir ../originGUI build", +"dev": "pnpm run menu && plasmo dev", +"build": "pnpm run menu && plasmo build", +"package": "pnpm run menu && plasmo package", +"typecheck": "pnpm run menu && tsc --noEmit", +``` +(leave `dev:firefox`, `build:firefox`, `package:firefox`, `test` unchanged). + +- [ ] **Step 5: Build and verify** + +Run: `cd extension && pnpm typecheck && pnpm build` +Expected: success. Then `grep -c "startOriginMenu\|origin-menu" build/chrome-mv3-prod/menu.*.js` is ≥ 1. The menu code is inside the content script. + +Run: `head -c 200 ../originGUI/dist/bundle.js; tail -c 60 ../originGUI/dist/bundle.js`. The bundle must not end with `/* DEV BUNDLE */`. + +- [ ] **Step 6: LIVE CHECKPOINT B (user)** + +Restart `pnpm dev`, reload the unpacked extension, and hard-reload Prodigy. Verify that `[Origin] menu started` is logged, the menu renders with ▲/▼, Shift toggles it, the "Disable math" hack (battle.ts `setConstant(EDUCATION_ENABLED,false)`) works in a battle, and membership on/off works. + +- [ ] **Step 7: Commit** + +```bash +git add .gitignore originGUI/build.mjs originGUI/src originGUI/dist/bundle.js extension/contents/menu.ts extension/package.json +git commit -m "feat: package originGUI into the Chrome extension, drop remote menu loading and evals" +``` + +--- + +### Task 7: Remove the dead pipeline, tighten the manifest, update docs + +**Files:** +- Delete: `extension/lib/{bundle-cache,manifest,patches,patch-urls}.ts`, `extension/tests/{bundle-cache,manifest,patches,patch-urls,integration}.test.ts` +- Modify: `extension/popup.tsx` (drop Developer Options / URL overrides), `extension/package.json` (manifest permissions) +- Modify: `CLAUDE.md`, `.claude/architecture.md`, `.claude/workflow.md` + +- [ ] **Step 1: Delete pipeline code and its tests** + +```bash +git rm extension/lib/bundle-cache.ts extension/lib/manifest.ts extension/lib/patches.ts extension/lib/patch-urls.ts \ + extension/tests/bundle-cache.test.ts extension/tests/manifest.test.ts extension/tests/patches.test.ts \ + extension/tests/patch-urls.test.ts extension/tests/integration.test.ts +grep -rn "lib/patches\|lib/manifest\|lib/bundle-cache\|lib/patch-urls" extension --include=*.ts --include=*.tsx | grep -v node_modules | grep -v "^extension/firefox" +``` +Expected: grep prints nothing. + +- [ ] **Step 2: Popup: remove the manifest/menu URL overrides** + +In `extension/popup.tsx`: delete the `manifestUrl`, `guiUrl`, `saved`, `devOpen`, `devUnlocked` and `challengeInput` state, the `useEffect` that reads `chrome.storage.local`, and `handleSave`/`handleReset`. Delete the JSX from `{/* Developer Options accordion */}` through the end of its `` block. Remove imports that become unused (check `Save`, `RotateCcw`, `ChevronDown`, `motion`, `AnimatePresence`, `useEffect`, `useState`). Then run `pnpm typecheck`. It must pass with no unused-symbol errors, and `grep -n "chrome.storage" popup.tsx` must print nothing. + +- [ ] **Step 3: Manifest permissions** + +In `extension/package.json` → `manifest`: +```json +"permissions": ["declarativeNetRequest"], +"host_permissions": ["*://*.prodigygame.com/*"], +``` +Check: `grep -rn "chrome.storage" extension --include=*.ts --include=*.tsx | grep -v node_modules | grep -v firefox` prints nothing. + +- [ ] **Step 4: Docs** + +`CLAUDE.md`: replace rules 5 and 6 with: +``` +5. **No remote code on `chrome/packaged-runtime`** — the Chrome build must never fetch-and-run JavaScript, use `onreset`, `eval`, or `new Function`. Hooks live in `extension/lib/runtime/`; the menu is packaged via `extension/contents/menu.ts`. Master keeps the P-NP `onreset` pipeline for Edge/Firefox. +6. **Graceful degradation** — a hook target that stops resolving logs `[Origin] hook target missing: `; the other hooks keep working. A missing target means a Chrome Web Store resubmission. +``` +`.claude/architecture.md`: replace the `extension/` bullet list, the "Injection method" / "Content script" / "Window globals" / "DOM attributes" / "Storage keys" lines, and the `extension/` part of Key Files, with a description of: `contents/runtime.ts` (defineProperty hook → resolve → bypasses + `window._`), `contents/menu.ts`, `lib/runtime/{modules,resolve,bypasses,api,ready}.ts`, `background.ts` (image redirects only), window globals `_` and `__ORIGIN_READY__`, event `origin:ready`, and the table of hook targets from the spec. +`.claude/workflow.md`: under Testing, replace "Verify DNR rules are active" with the Task 5 checkpoint A list. + +- [ ] **Step 5: Full verification** + +```bash +cd extension && pnpm test && pnpm typecheck && pnpm build +grep -rlE "onreset|raw\.githubusercontent\.com/ProdigyPXP/(P-NP|ProdigyOrigin/[^\"]*/originGUI/dist)" build/chrome-mv3-prod || echo "clean: no remote-code references" +grep -rnoE "\beval\(|new Function\(" build/chrome-mv3-prod | head +``` +Expected: tests, typecheck and build pass, and the first grep prints `clean: ...`. Any hit from the second grep must be inside third-party library code (e.g., sweetalert2, React). Record it in the final report. Play Origin code must have none. + +- [ ] **Step 6: Commit** + +```bash +git add -A extension/popup.tsx extension/package.json CLAUDE.md .claude/architecture.md .claude/workflow.md +git commit -m "chore(extension): drop P-NP pipeline, URL overrides and unused permissions from Chrome build" +``` diff --git a/docs/superpowers/specs/2026-09-24-chrome-packaged-runtime-design.md b/docs/superpowers/specs/2026-09-24-chrome-packaged-runtime-design.md index 777f342..83be789 100644 --- a/docs/superpowers/specs/2026-09-24-chrome-packaged-runtime-design.md +++ b/docs/superpowers/specs/2026-09-24-chrome-packaged-runtime-design.md @@ -18,14 +18,14 @@ Success criteria: ## Why hooks work here -`game.min.js` is one webpack bundle. Its runtime tags every ESM exports object via `Object.defineProperty(exports, Symbol.toStringTag, {value: "Module"})`. A MAIN-world content script at `document_start` wraps `Object.defineProperty`, keeps a list of those exports objects, and passes everything else straight through. Targets are resolved lazily, after the game boots, by name or shape. Module ids are never used. +`game.min.js` is one webpack bundle. Its runtime helper `__webpack_require__.d` defines every export as `Object.defineProperty(exports, key, {enumerable: true, get})`. That's 1238 modules; only 5 also get the `Symbol.toStringTag` "Module" tag. A MAIN-world content script at `document_start` wraps `Object.defineProperty`, keeps a set of every object that receives a descriptor of exactly that shape (or the "Module" tag), and passes each call straight through. Targets are resolved lazily, after the game boots, by name or shape. Module ids are never used. | Old P-NP rule | Packaged replacement | |---|---| | `singleton-exposure` | Export that is a class with a static `instance` getter and a `prodigy` prototype getter (module 35120 `q` today). `_.instance` = `q.instance`. | | `expose-constants` | Export whose `.constants` object has key `"GameConstants.Build.VERSION"` (module 34829 today). Same Map-like `get`/`set`/`has` + `.constants` self-alias as the old suffix. | | `answer-question-bypass` | Component registry (export object with key `OpenQuestionInterface`, filled by the `EV(name, path)` decorator). Wrap `OpenQuestionInterface.prototype.answerQuestion`. | -| `external-factory-bypass` | Action registry (export object with key `AnswerQuestion`, filled by `ba9(name)`). Wrap `AnswerQuestion.prototype.execute`; bypass calls `this.finish({answerCorrect, responseTime: 0})`. | +| `external-factory-bypass` | The action registry (`Ie` in module 62459) is not exported. Instead, find the exported base action class (the only class whose prototype *owns* `init`, `execute`, `finish`, `findParameter`, `validateParameters`) and wrap its `init`. The action factory calls `init(data)` with `data.Type === "AnswerQuestion"`; on the first such call, wrap that subclass's own `execute`. The bypass calls `this.finish({answerCorrect, responseTime: 0})`. | | `open-question-bypass` | Exported class whose prototype has `openQuestionInterfaceThenEmitNotifications` (module 82142 `gT` today). Wrap it; bypass calls the callback `(true, 10, 1, false, false, {})`. | | `safe-bind`, semaphore guard | Dropped. They only guarded against `onreset` running the game twice. | @@ -39,9 +39,11 @@ Registry keys are prefab serialization names, so minification can't rename them. - `modules.ts`: `defineProperty` hook + the captured-exports list. - `resolve.ts`: `findSingletonClass`, `findConstants`, `findRegistry(key)`, `findClassWithMethod(name)`, each taking the exports list. - `bypasses.ts`: the three prototype wraps. Idempotent, marked with a symbol so they never double-wrap. - - `api.ts`: builds the `window._` surface ported from P-NP `wrappers.ts` (`instance`, `constants`, `player`, `network`, `gameData`, `localizer`, `membership`, `hack`, `functions.escapeBattle`, `functions.setMembership`, `__pnp_discoverService`). It re-applies itself when lodash replaces `window._`, same as the old 500 ms poll. When the singleton and constants are resolved, it dispatches `origin:ready` on `window`. + - `api.ts`: builds the `window._` surface the menu actually reads, ported from P-NP `wrappers.ts`: `instance`, `constants`, `player`, `network`, `gameData`, `membership`, `functions.setMembership`. `localizer`, `hack`, `variables` and `escapeBattle` are dropped because nothing in originGUI reads them. `setMembership` is attached to whatever `_.functions` already is (lodash's `functions`), not replacing it. The API re-applies itself when lodash replaces `window._`, same as the old 500 ms poll. + - `ready.ts`: `origin:ready` event + flag. Fired once the singleton has `prodigy` and `_.player` resolves (the menu captures `_.player` at load). + - Every lib/runtime module imports only *types* from its siblings. The node test runner can't resolve extensionless value imports, so the wiring lives in `contents/runtime.ts`. - **`extension/contents/runtime.ts`**: MAIN world, `document_start`, `https://math.prodigygame.com/*`. Installs the hook, then the API and bypasses once resolution succeeds. If a target is still missing after the game boots, it logs `[Origin] hook target missing: ` and continues with what it has (graceful degradation). -- **`extension/contents/menu.ts`**: MAIN world, `document_idle`. Imports the built originGUI bundle so the menu code sits inside the content script. Waits for `origin:ready` before running the menu. +- **`extension/contents/menu.ts`**: MAIN world, `document_idle`. `originGUI/build.mjs` also emits `dist/menu.js` (`export default function startOriginMenu () { }`, gitignored), and Parcel bundles it into this content script. The script waits for `origin:ready`, then calls `startOriginMenu()`. The extension's `dev`/`build`/`package`/`typecheck` scripts build originGUI first. - **originGUI changes** (on this branch only): remove "Update menu", the beta branch loader, the eval console, and the dev socket `eval`. Replace the template-string `eval`s in `player.ts` and `pets.ts` with closures. Data `fetch`es (status message JSON, Prodigy API, asset URLs) stay; they load data, not code. ## Removed from the Chrome extension From f01e2dfe70e105d6a953f73ccd3b03176905eba9 Mon Sep 17 00:00:00 2001 From: Alexey Fedorov Date: Thu, 24 Sep 2026 01:46:15 -0500 Subject: [PATCH 03/11] feat(extension): capture webpack export objects via defineProperty hook Also: ignore .superpowers/ scratch, and fix extension typecheck under TS 7 (bundler resolution; exclude firefox/ and node-run tests). Co-Authored-By: Claude Opus 5.5 --- .gitignore | 1 + extension/lib/runtime/modules.ts | 31 ++++++++++++++ extension/tests/runtime-modules.test.ts | 57 +++++++++++++++++++++++++ extension/tsconfig.json | 9 +++- 4 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 extension/lib/runtime/modules.ts create mode 100644 extension/tests/runtime-modules.test.ts diff --git a/.gitignore b/.gitignore index 3b353d1..aeac061 100644 --- a/.gitignore +++ b/.gitignore @@ -66,3 +66,4 @@ extension/firefox/.plasmo/ # MCP debug config .mcp.json .worktrees/ +.superpowers/ diff --git a/extension/lib/runtime/modules.ts b/extension/lib/runtime/modules.ts new file mode 100644 index 0000000..720742b --- /dev/null +++ b/extension/lib/runtime/modules.ts @@ -0,0 +1,31 @@ +// extension/lib/runtime/modules.ts +// Captures webpack export objects as Prodigy's unmodified game.min.js creates +// them. webpack's __webpack_require__.d defines every export as +// Object.defineProperty(exports, key, { enumerable: true, get }), and +// __webpack_require__.r tags a few namespaces with Symbol.toStringTag "Module". +// Wrapping Object.defineProperty lets packaged code see those objects without +// rewriting the game's source. + +type DefineProperty = ObjectConstructor["defineProperty"] + +export const isWebpackExportDescriptor = (key: PropertyKey, desc: unknown): boolean => { + if (!desc || typeof desc !== "object") return false + const d = desc as PropertyDescriptor + if (key === Symbol.toStringTag) return d.value === "Module" + return d.enumerable === true && typeof d.get === "function" && Object.keys(d).length === 2 +} + +export const installModuleHook = ( + objectCtor: { defineProperty: DefineProperty }, + sink: Set +): (() => void) => { + const original = objectCtor.defineProperty + const hooked = function defineProperty(target: object, key: PropertyKey, desc: PropertyDescriptor) { + if (isWebpackExportDescriptor(key, desc)) sink.add(target) + return original(target, key, desc) + } as DefineProperty + objectCtor.defineProperty = hooked + return () => { + if (objectCtor.defineProperty === hooked) objectCtor.defineProperty = original + } +} diff --git a/extension/tests/runtime-modules.test.ts b/extension/tests/runtime-modules.test.ts new file mode 100644 index 0000000..41dfeb3 --- /dev/null +++ b/extension/tests/runtime-modules.test.ts @@ -0,0 +1,57 @@ +// extension/tests/runtime-modules.test.ts +import { describe, it } from "node:test" +import assert from "node:assert/strict" +import { installModuleHook, isWebpackExportDescriptor } from "../lib/runtime/modules.ts" + +const makeCtor = () => ({ defineProperty: Object.defineProperty }) as { defineProperty: ObjectConstructor["defineProperty"] } + +// Mirrors game.min.js: __webpack_require__.d=(E,w)=>{for(var T in w)o(w,T)&&!o(E,T)&&Object.defineProperty(E,T,{enumerable:!0,get:w[T]})} +const webpackD = (ctor: ReturnType) => (exports: object, definition: Record unknown>) => { + for (const key in definition) { + if (Object.prototype.hasOwnProperty.call(definition, key) && !Object.prototype.hasOwnProperty.call(exports, key)) { + ctor.defineProperty(exports, key, { enumerable: true, get: definition[key] }) + } + } +} + +describe("isWebpackExportDescriptor", () => { + it("accepts webpack's {enumerable, get} export descriptor", () => { + assert.equal(isWebpackExportDescriptor("q", { enumerable: true, get: () => 1 }), true) + }) + it("accepts the Module toStringTag", () => { + assert.equal(isWebpackExportDescriptor(Symbol.toStringTag, { value: "Module" }), true) + }) + it("rejects other descriptors", () => { + assert.equal(isWebpackExportDescriptor("q", { value: 1 }), false) + assert.equal(isWebpackExportDescriptor("q", { enumerable: true, configurable: true, get: () => 1 }), false) + assert.equal(isWebpackExportDescriptor("q", undefined), false) + }) +}) + +describe("installModuleHook", () => { + it("captures export objects defined through the hooked defineProperty", () => { + const ctor = makeCtor() + const sink = new Set() + installModuleHook(ctor, sink) + const exports = {} + webpackD(ctor)(exports, { q: () => 42 }) + assert.ok(sink.has(exports)) + assert.equal((exports as { q: number }).q, 42) + }) + it("passes non-export defines through without capturing", () => { + const ctor = makeCtor() + const sink = new Set() + installModuleHook(ctor, sink) + const obj = {} + ctor.defineProperty(obj, "x", { value: 1, writable: true }) + assert.equal(sink.size, 0) + assert.equal((obj as { x: number }).x, 1) + }) + it("uninstall restores the original", () => { + const ctor = makeCtor() + const uninstall = installModuleHook(ctor, new Set()) + assert.notEqual(ctor.defineProperty, Object.defineProperty) + uninstall() + assert.equal(ctor.defineProperty, Object.defineProperty) + }) +}) diff --git a/extension/tsconfig.json b/extension/tsconfig.json index 8ed3b43..bc891cb 100644 --- a/extension/tsconfig.json +++ b/extension/tsconfig.json @@ -5,11 +5,18 @@ "ignoreDeprecations": "6.0", "types": [ "chrome" - ] + ], + "moduleResolution": "bundler" }, "include": [ ".plasmo/index.d.ts", "**/*.ts", "**/*.tsx" + ], + "exclude": [ + "node_modules", + "build", + "firefox", + "tests" ] } From d583fb6d9f7df7b90bcc3dd3bb055f4835bee285 Mon Sep 17 00:00:00 2001 From: Alexey Fedorov Date: Thu, 24 Sep 2026 01:46:24 -0500 Subject: [PATCH 04/11] feat(extension): resolve hook targets from captured webpack exports Co-Authored-By: Claude Opus 5.5 --- extension/lib/runtime/resolve.ts | 90 +++++++++++++++++++++++++ extension/tests/runtime-resolve.test.ts | 78 +++++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 extension/lib/runtime/resolve.ts create mode 100644 extension/tests/runtime-resolve.test.ts diff --git a/extension/lib/runtime/resolve.ts b/extension/lib/runtime/resolve.ts new file mode 100644 index 0000000..df08ec4 --- /dev/null +++ b/extension/lib/runtime/resolve.ts @@ -0,0 +1,90 @@ +// extension/lib/runtime/resolve.ts +// Finds the game objects Play Origin hooks, by shape or by names minification +// can't touch. Uses property descriptors only, so no game getters or methods run +// apart from webpack's own export getters. + +export type AnyClass = Function & { prototype: any } + +export type Targets = { + singletonClass?: AnyClass & { readonly instance?: any } + constants?: Record + componentRegistry?: Record + baseActionClass?: AnyClass + towerTownClass?: AnyClass +} + +export type TargetName = keyof Targets + +export const TARGET_NAMES: readonly TargetName[] = [ + "singletonClass", + "constants", + "componentRegistry", + "baseActionClass", + "towerTownClass" +] + +const BASE_ACTION_METHODS = ["init", "execute", "finish", "findParameter", "validateParameters"] + +const descriptor = (obj: object, key: PropertyKey) => Object.getOwnPropertyDescriptor(obj, key) + +const isClass = (v: unknown): v is AnyClass => + typeof v === "function" && typeof (v as AnyClass).prototype === "object" && (v as AnyClass).prototype !== null + +const ownsMethod = (cls: AnyClass, name: string) => typeof descriptor(cls.prototype, name)?.value === "function" + +// module 35120: class with static `instance` getter whose instances expose `prodigy` +const isSingletonClass = (v: unknown): v is NonNullable => + isClass(v) && typeof descriptor(v, "instance")?.get === "function" && typeof descriptor(v.prototype, "prodigy")?.get === "function" + +// module 34829: `X.constants = {"GameConstants.Build.VERSION": ...}` +const constantsOf = (v: unknown): Record | undefined => { + if (!v || (typeof v !== "object" && typeof v !== "function")) return undefined + const c = descriptor(v, "constants")?.value + return c && typeof c === "object" && Object.prototype.hasOwnProperty.call(c, "GameConstants.Build.VERSION") ? c : undefined +} + +// module 40794 export X, filled by the EV("OpenQuestionInterface", …) decorator +const isComponentRegistry = (v: unknown): v is Record => + !!v && typeof v === "object" && isClass(descriptor(v, "OpenQuestionInterface")?.value) + +// module 62459 export rcl: subclasses only own `validate`/`execute` +const isBaseActionClass = (v: unknown): v is AnyClass => isClass(v) && BASE_ACTION_METHODS.every((m) => ownsMethod(v, m)) + +// module 82142 export gT (Tower Town) +const isTowerTownClass = (v: unknown): v is AnyClass => isClass(v) && ownsMethod(v, "openQuestionInterfaceThenEmitNotifications") + +function* exportValues(exportsObjects: Iterable): Generator { + for (const obj of exportsObjects) { + let keys: string[] + try { + keys = Object.keys(obj) + } catch { + continue + } + for (const key of keys) { + let value: unknown + try { + value = (obj as Record)[key] + } catch { + continue // module still evaluating (TDZ) + } + yield value + } + } +} + +export const missingTargets = (t: Targets): TargetName[] => TARGET_NAMES.filter((n) => !t[n]) + +export const resolveTargets = (exportsObjects: Iterable, found: Targets): Targets => { + const t: Targets = { ...found } + if (missingTargets(t).length === 0) return t + for (const v of exportValues(exportsObjects)) { + if (!t.singletonClass && isSingletonClass(v)) t.singletonClass = v + if (!t.constants) t.constants = constantsOf(v) + if (!t.componentRegistry && isComponentRegistry(v)) t.componentRegistry = v + if (!t.baseActionClass && isBaseActionClass(v)) t.baseActionClass = v + if (!t.towerTownClass && isTowerTownClass(v)) t.towerTownClass = v + if (missingTargets(t).length === 0) break + } + return t +} diff --git a/extension/tests/runtime-resolve.test.ts b/extension/tests/runtime-resolve.test.ts new file mode 100644 index 0000000..ddfad44 --- /dev/null +++ b/extension/tests/runtime-resolve.test.ts @@ -0,0 +1,78 @@ +// extension/tests/runtime-resolve.test.ts +import { describe, it } from "node:test" +import assert from "node:assert/strict" +import { missingTargets, resolveTargets, TARGET_NAMES } from "../lib/runtime/resolve.ts" + +const exportsOf = (values: Record): object => { + const e = {} + for (const k of Object.keys(values)) Object.defineProperty(e, k, { enumerable: true, get: () => values[k] }) + return e +} + +// Shapes copied from game.min.js (module ids as of 2026.18.1 in comments). +class Singleton { // 35120 q + static _instance: unknown = null + static get instance() { return this._instance } + get game() { return null } + get prodigy() { return null } +} +class GameOnlySingleton { // 61806 W: decoy, has instance+game but no prodigy + static get instance() { return null } + get game() { return null } +} +class ConstantsHolder { // 34829 s + static constants = { "GameConstants.Build.VERSION": "2026.18.1", "GameConstants.Debug.EDUCATION_ENABLED": true } +} +class OpenQuestionInterface { answerQuestion() {} } +const componentRegistry = { OpenQuestionInterface } // 40794 X +class BaseAction { // 62459 rcl + init() {} execute() {} finish() {} findParameter() {} validateParameters() {} +} +class AnswerQuestionAction extends BaseAction { execute() {} } // decoy: owns execute only +class TowerTown { openQuestionInterfaceThenEmitNotifications() {} } // 82142 gT + +const allExports = () => [ + exportsOf({ W: GameOnlySingleton }), + exportsOf({ q: Singleton }), + exportsOf({ A: {}, s: ConstantsHolder }), + exportsOf({ X: componentRegistry, u: class {} }), + exportsOf({ rcl: BaseAction, sub: AnswerQuestionAction }), + exportsOf({ gT: TowerTown }) +] + +describe("resolveTargets", () => { + it("finds every target by shape", () => { + const t = resolveTargets(allExports(), {}) + assert.equal(t.singletonClass, Singleton) + assert.equal(t.constants, ConstantsHolder.constants) + assert.equal(t.componentRegistry, componentRegistry) + assert.equal(t.baseActionClass, BaseAction) + assert.equal(t.towerTownClass, TowerTown) + assert.deepEqual(missingTargets(t), []) + }) + + it("skips getters that throw", () => { + const tdz = {} + Object.defineProperty(tdz, "S", { enumerable: true, get() { throw new ReferenceError("Cannot access 'S' before initialization") } }) + const t = resolveTargets([tdz, ...allExports()], {}) + assert.equal(t.singletonClass, Singleton) + }) + + it("resolves the targets that exist and reports the rest", () => { + const t = resolveTargets([exportsOf({ q: Singleton })], {}) + assert.equal(t.singletonClass, Singleton) + assert.deepEqual(missingTargets(t), TARGET_NAMES.filter((n) => n !== "singletonClass")) + }) + + it("keeps already-found targets and fills the rest later", () => { + const first = resolveTargets([exportsOf({ q: Singleton })], {}) + const second = resolveTargets(allExports(), first) + assert.equal(second.singletonClass, Singleton) + assert.equal(second.towerTownClass, TowerTown) + }) + + it("does not treat a registry that lacks OpenQuestionInterface yet as found", () => { + const t = resolveTargets([exportsOf({ X: {} })], {}) + assert.equal(t.componentRegistry, undefined) + }) +}) From 747e20fa85da0e738f6e471231aeebdb52b6212d Mon Sep 17 00:00:00 2001 From: Alexey Fedorov Date: Thu, 24 Sep 2026 01:46:33 -0500 Subject: [PATCH 05/11] feat(extension): packaged education bypasses as prototype wraps Co-Authored-By: Claude Opus 5.5 --- extension/lib/runtime/bypasses.ts | 80 ++++++++++++ extension/tests/runtime-bypasses.test.ts | 156 +++++++++++++++++++++++ 2 files changed, 236 insertions(+) create mode 100644 extension/lib/runtime/bypasses.ts create mode 100644 extension/tests/runtime-bypasses.test.ts diff --git a/extension/lib/runtime/bypasses.ts b/extension/lib/runtime/bypasses.ts new file mode 100644 index 0000000..bf8b124 --- /dev/null +++ b/extension/lib/runtime/bypasses.ts @@ -0,0 +1,80 @@ +// extension/lib/runtime/bypasses.ts +// Education bypasses, as prototype wraps. Replaces the P-NP regex rules +// answer-question-bypass, external-factory-bypass and open-question-bypass, +// which injected the same early returns into game.min.js source. + +import type { AnyClass } from "./resolve" + +export type GetConstants = () => Record | undefined + +const EDUCATION_ENABLED = "GameConstants.Debug.EDUCATION_ENABLED" +const CORRECT_PERCENT = "GameConstants.Debug.AUTO_ANSWER_CORRECT_PERCENT" +const WRAPPED = Symbol.for("playOrigin.wrapped") + +type AnyFn = (...args: any[]) => any + +const bypassed = (c: Record | undefined): c is Record => !!c && !c[EDUCATION_ENABLED] + +const rollCorrect = (c: Record, random: () => number) => + random() < ((c[CORRECT_PERCENT] as number) || 1) + +// Wraps an *own* prototype method once. Returns false if there is none. +const wrapOwnMethod = (proto: any, name: string, make: (original: AnyFn) => AnyFn): boolean => { + const original = Object.getOwnPropertyDescriptor(proto, name)?.value + if (typeof original !== "function") return false + if ((original as any)[WRAPPED]) return true + const wrapped = make(original) + ;(wrapped as any)[WRAPPED] = true + proto[name] = wrapped + return true +} + +export const installOpenQuestionBypass = ( + cls: AnyClass, + getConstants: GetConstants, + random: () => number = Math.random +): boolean => + wrapOwnMethod(cls.prototype, "answerQuestion", (original) => + function (this: any, ...args: unknown[]) { + const c = getConstants() + if (!bypassed(c)) return original.apply(this, args) + const correct = rollCorrect(c, random) + this.onQuestionAnswered.dispatch(correct, 0, null) + if (correct) this.onQuestionAnsweredCorrectly.dispatch(0, null) + else this.onQuestionAnsweredIncorrectly.dispatch(0, null) + } + ) + +// The action registry is module-private, so catch AnswerQuestion when the +// action factory calls init(data) with data.Type === "AnswerQuestion". +export const installAnswerQuestionActionBypass = ( + baseActionClass: AnyClass, + getConstants: GetConstants, + random: () => number = Math.random +): boolean => + wrapOwnMethod(baseActionClass.prototype, "init", (originalInit) => + function (this: any, ...args: unknown[]) { + const result = originalInit.apply(this, args) + const data = args[0] as { Type?: unknown } | null | undefined + const proto = Object.getPrototypeOf(this) + if (data?.Type === "AnswerQuestion" && proto !== baseActionClass.prototype) { + wrapOwnMethod(proto, "execute", (originalExecute) => + function (this: any, ...executeArgs: unknown[]) { + const c = getConstants() + if (!bypassed(c)) return originalExecute.apply(this, executeArgs) + this.finish({ answerCorrect: rollCorrect(c, random), responseTime: 0 }) + } + ) + } + return result + } + ) + +export const installTowerTownBypass = (cls: AnyClass, getConstants: GetConstants): boolean => + wrapOwnMethod(cls.prototype, "openQuestionInterfaceThenEmitNotifications", (original) => + function (this: any, ...args: unknown[]) { + if (!bypassed(getConstants())) return original.apply(this, args) + const done = args[4] + if (typeof done === "function") done(true, 10, 1, false, false, {}) + } + ) diff --git a/extension/tests/runtime-bypasses.test.ts b/extension/tests/runtime-bypasses.test.ts new file mode 100644 index 0000000..d64d2eb --- /dev/null +++ b/extension/tests/runtime-bypasses.test.ts @@ -0,0 +1,156 @@ +// extension/tests/runtime-bypasses.test.ts +import { describe, it } from "node:test" +import assert from "node:assert/strict" +import { + installAnswerQuestionActionBypass, + installOpenQuestionBypass, + installTowerTownBypass +} from "../lib/runtime/bypasses.ts" + +const EDU = "GameConstants.Debug.EDUCATION_ENABLED" +const PCT = "GameConstants.Debug.AUTO_ANSWER_CORRECT_PERCENT" + +const signal = () => { + const calls: unknown[][] = [] + return { calls, dispatch: (...args: unknown[]) => { calls.push(args) } } +} + +const makeOpenQuestionClass = () => + class OpenQuestionInterface { + onQuestionAnswered = signal() + onQuestionAnsweredCorrectly = signal() + onQuestionAnsweredIncorrectly = signal() + opened = 0 + answerQuestion() { this.opened++ } + } + +describe("installOpenQuestionBypass", () => { + it("runs the original when education is enabled", () => { + const C = makeOpenQuestionClass() + const constants: Record = { [EDU]: true, [PCT]: 1 } + installOpenQuestionBypass(C, () => constants) + const q = new C() + q.answerQuestion() + assert.equal(q.opened, 1) + assert.equal(q.onQuestionAnswered.calls.length, 0) + }) + + it("answers correctly without opening when education is disabled", () => { + const C = makeOpenQuestionClass() + installOpenQuestionBypass(C, () => ({ [EDU]: false, [PCT]: 1 }), () => 0) + const q = new C() + q.answerQuestion() + assert.equal(q.opened, 0) + assert.deepEqual(q.onQuestionAnswered.calls, [[true, 0, null]]) + assert.deepEqual(q.onQuestionAnsweredCorrectly.calls, [[0, null]]) + assert.equal(q.onQuestionAnsweredIncorrectly.calls.length, 0) + }) + + it("answers incorrectly when the roll misses the percentage", () => { + const C = makeOpenQuestionClass() + installOpenQuestionBypass(C, () => ({ [EDU]: false, [PCT]: 0.5 }), () => 0.9) + const q = new C() + q.answerQuestion() + assert.deepEqual(q.onQuestionAnswered.calls, [[false, 0, null]]) + assert.deepEqual(q.onQuestionAnsweredIncorrectly.calls, [[0, null]]) + }) + + it("follows the flag live: bypass off again once education is re-enabled", () => { + const C = makeOpenQuestionClass() + const constants: Record = { [EDU]: false } + installOpenQuestionBypass(C, () => constants, () => 0) + const q = new C() + q.answerQuestion() + constants[EDU] = true + q.answerQuestion() + assert.equal(q.opened, 1) + }) + + it("runs the original while constants are unresolved", () => { + const C = makeOpenQuestionClass() + installOpenQuestionBypass(C, () => undefined) + const q = new C() + q.answerQuestion() + assert.equal(q.opened, 1) + }) + + it("wraps once", () => { + const C = makeOpenQuestionClass() + installOpenQuestionBypass(C, () => undefined) + const first = C.prototype.answerQuestion + assert.equal(installOpenQuestionBypass(C, () => undefined), true) + assert.equal(C.prototype.answerQuestion, first) + }) + + it("returns false when the method is missing", () => { + assert.equal(installOpenQuestionBypass(class {}, () => undefined), false) + }) +}) + +describe("installAnswerQuestionActionBypass", () => { + const make = () => { + class BaseAction { + data: any = null + finished: unknown = undefined + init(data: any) { this.data = data } + execute() {} + finish(result: unknown) { this.finished = result } + findParameter() { return null } + validateParameters() { return true } + } + class AnswerQuestion extends BaseAction { executed = false; execute() { this.executed = true } } + class Other extends BaseAction { executed = false; execute() { this.executed = true } } + return { BaseAction, AnswerQuestion, Other } + } + + it("finishes AnswerQuestion actions without asking when education is disabled", () => { + const { BaseAction, AnswerQuestion } = make() + installAnswerQuestionActionBypass(BaseAction, () => ({ [EDU]: false }), () => 0) + const a = new AnswerQuestion() + a.init({ Type: "AnswerQuestion" }) + a.execute() + assert.equal(a.executed, false) + assert.deepEqual(a.finished, { answerCorrect: true, responseTime: 0 }) + }) + + it("runs the original AnswerQuestion when education is enabled", () => { + const { BaseAction, AnswerQuestion } = make() + installAnswerQuestionActionBypass(BaseAction, () => ({ [EDU]: true })) + const a = new AnswerQuestion() + a.init({ Type: "AnswerQuestion" }) + a.execute() + assert.equal(a.executed, true) + }) + + it("leaves other actions and the base execute alone", () => { + const { BaseAction, Other } = make() + const baseExecute = BaseAction.prototype.execute + installAnswerQuestionActionBypass(BaseAction, () => ({ [EDU]: false })) + const o = new Other() + o.init({ Type: "Other" }) + o.execute() + assert.equal(o.executed, true) + assert.equal(BaseAction.prototype.execute, baseExecute) + }) +}) + +describe("installTowerTownBypass", () => { + class TowerTown { + opened = 0 + openQuestionInterfaceThenEmitNotifications(_e: unknown, _w: unknown, _t: unknown, _s: unknown, _cb?: Function) { this.opened++ } + } + + it("calls the completion callback as a correct answer", () => { + installTowerTownBypass(TowerTown, () => ({ [EDU]: false })) + const t = new TowerTown() + const calls: unknown[][] = [] + t.openQuestionInterfaceThenEmitNotifications(1, true, null, false, (...a: unknown[]) => calls.push(a)) + assert.equal(t.opened, 0) + assert.deepEqual(calls, [[true, 10, 1, false, false, {}]]) + }) + + it("tolerates a missing callback", () => { + installTowerTownBypass(TowerTown, () => ({ [EDU]: false })) + assert.doesNotThrow(() => new TowerTown().openQuestionInterfaceThenEmitNotifications(1, true, null, false)) + }) +}) From 483ec1f6544d79eff0b82cc5971e074c19931b77 Mon Sep 17 00:00:00 2001 From: Alexey Fedorov Date: Thu, 24 Sep 2026 01:46:54 -0500 Subject: [PATCH 06/11] feat(extension): packaged window._ API and origin:ready signal Co-Authored-By: Claude Opus 5.5 --- extension/lib/runtime/api.ts | 161 ++++++++++++++++++++++++++++ extension/lib/runtime/ready.ts | 16 +++ extension/tests/runtime-api.test.ts | 129 ++++++++++++++++++++++ 3 files changed, 306 insertions(+) create mode 100644 extension/lib/runtime/api.ts create mode 100644 extension/lib/runtime/ready.ts create mode 100644 extension/tests/runtime-api.test.ts diff --git a/extension/lib/runtime/api.ts b/extension/lib/runtime/api.ts new file mode 100644 index 0000000..048f4f5 --- /dev/null +++ b/extension/lib/runtime/api.ts @@ -0,0 +1,161 @@ +// extension/lib/runtime/api.ts +// The `window._` surface originGUI reads. Ported from the old P-NP suffix +// (P-NP/src/wrappers.ts), minus the parts that only existed because the +// patched bundle ran twice. + +import type { Targets } from "./resolve" + +type OriginApiDeps = { + singletonClass: NonNullable + constants: Record +} + +const API_MARK = "__originApi" +const SERVICE_ID = /^[0-9a-f]{2,4}-[0-9a-f]{2,6}$/ + +const defineHidden = (target: object, key: PropertyKey, value: unknown) => + Object.defineProperty(target, key, { value, configurable: true, writable: true }) + +const defineGetter = (target: object, key: PropertyKey, get: () => unknown) => + Object.defineProperty(target, key, { get, configurable: true, enumerable: true }) + +// Service ids drift every build; enumerate Inversify bindings and match by shape. +export const discoverService = (gc: any, matches: (inst: any) => boolean): any => { + let map: Map | undefined + try { + map = gc._inversifyContainer._bindingDictionary._map + } catch { + return null + } + if (!map || typeof map.keys !== "function") return null + for (const id of map.keys()) { + if (typeof id !== "string" || !SERVICE_ID.test(id)) continue + try { + const inst = gc.get(id) + if (inst && matches(inst)) return inst + } catch {} + } + return null +} + +// The menu writes `_.constants.constants[key]` and reads `_.constants.get(key)`; +// both must hit the object the game itself reads. +export const addConstantsApi = (raw: Record): Record => { + if (typeof raw.get !== "function") { + defineHidden(raw, "get", (key: string) => raw[key]) + defineHidden(raw, "set", (key: string, value: unknown) => { + raw[key] = value + return raw + }) + defineHidden(raw, "has", (key: string) => key in raw) + defineHidden(raw, "constants", raw) + } + return raw +} + +const isPlayerService = (inst: any) => { + try { + const p = inst.player + return !!p && typeof p === "object" && "data" in p + } catch { + return false + } +} +const isNetworkManager = (inst: any) => + typeof inst.getCharData === "function" && "processPlayer" in inst && typeof inst.sendZoneEvent === "function" +const isMembershipService = (inst: any) => typeof inst.hasFeatureAccess === "function" && "isMember" in inst + +export const createOriginApi = (deps: OriginApiDeps) => { + const services: { player?: any; network?: any; membership?: any } = {} + // Own hasFeatureAccess descriptor, if the service had one before we overrode it. + let membershipOriginal: { data: unknown; hasFeatureAccess?: PropertyDescriptor } | undefined + + const instance = () => deps.singletonClass.instance ?? null + const find = (key: keyof typeof services, matches: (inst: any) => boolean) => { + if (services[key]) return services[key] + const gc = instance()?.prodigy?.gameContainer + if (!gc) return null + const svc = discoverService(gc, matches) + if (svc) services[key] = svc + return svc + } + + const apply = (target: any) => { + defineGetter(target, "instance", instance) + Object.defineProperty(target, "constants", { + value: addConstantsApi(deps.constants), + configurable: true, + enumerable: true, + writable: true + }) + // The service caches the player; `.player` is a getter returning a fresh object. + defineGetter(target, "player", () => find("player", isPlayerService)?.player ?? null) + defineGetter(target, "gameData", () => { + try { + return instance()?.game?.state?.states?.get?.("Boot")?._gameData ?? null + } catch { + return null + } + }) + defineGetter(target, "network", () => { + const nm = find("network", isNetworkManager) + if (nm && !nm.game) { + try { + defineGetter(nm, "game", () => instance()?.game ?? null) + } catch {} + } + return nm + }) + defineGetter(target, "membership", () => find("membership", isMembershipService)) + + const setMembership = (active: boolean): boolean => { + const ms = find("membership", isMembershipService) + if (!ms) return false + if (!membershipOriginal) { + membershipOriginal = { data: ms._data, hasFeatureAccess: Object.getOwnPropertyDescriptor(ms, "hasFeatureAccess") } + } + if (active) { + const day = 86_400_000 + ms._data = { + active: true, + features: [], + membershipStartTs: new Date(Date.now() - day).toISOString(), + membershipEndTs: new Date(Date.now() + 10 * 365 * day).toISOString() + } + // memberTier derives from hasFeatureAccess, so this promotes to Ultra. + defineHidden(ms, "hasFeatureAccess", () => true) + try { ms.updateMembershipDates?.() } catch {} + try { target.player?.unlockMemberItems?.() } catch {} + } else { + ms._data = membershipOriginal.data + if (membershipOriginal.hasFeatureAccess) Object.defineProperty(ms, "hasFeatureAccess", membershipOriginal.hasFeatureAccess) + else delete ms.hasFeatureAccess + try { ms.updateMembershipDates?.() } catch {} + } + try { + const p = target.player + if (p) p.appearanceChanged = true + } catch {} + return true + } + // lodash owns `_.functions`; hang ours off it instead of replacing it. + if (target.functions == null) target.functions = Object.create(null) + defineHidden(target.functions, "setMembership", setMembership) + + defineHidden(target, API_MARK, true) + } + + return { + ensure(win: any): void { + if (win._ == null) win._ = {} + if (!win._[API_MARK]) apply(win._) + }, + isReady(win: any): boolean { + try { + return !!(instance()?.prodigy && win._?.player) + } catch { + return false + } + } + } +} diff --git a/extension/lib/runtime/ready.ts b/extension/lib/runtime/ready.ts new file mode 100644 index 0000000..fc82576 --- /dev/null +++ b/extension/lib/runtime/ready.ts @@ -0,0 +1,16 @@ +// extension/lib/runtime/ready.ts +// Tells the packaged menu the game is ready to be modded. + +export const READY_EVENT = "origin:ready" +const READY_FLAG = "__ORIGIN_READY__" + +export const markOriginReady = (win: any): void => { + if (win[READY_FLAG]) return + win[READY_FLAG] = true + win.dispatchEvent(new Event(READY_EVENT)) +} + +export const whenOriginReady = (win: any): Promise => + win[READY_FLAG] + ? Promise.resolve() + : new Promise((resolve) => win.addEventListener(READY_EVENT, () => resolve(), { once: true })) diff --git a/extension/tests/runtime-api.test.ts b/extension/tests/runtime-api.test.ts new file mode 100644 index 0000000..53e21b7 --- /dev/null +++ b/extension/tests/runtime-api.test.ts @@ -0,0 +1,129 @@ +// extension/tests/runtime-api.test.ts +import { describe, it } from "node:test" +import assert from "node:assert/strict" +import { addConstantsApi, createOriginApi, discoverService } from "../lib/runtime/api.ts" +import { markOriginReady, READY_EVENT, whenOriginReady } from "../lib/runtime/ready.ts" + +const makeGame = () => { + const player = { data: { name: "x" }, appearanceChanged: false, unlockMemberItems() { this.unlocked = true }, unlocked: false } + const membership = { _data: { active: false }, isMember: false, hasFeatureAccess() { return false }, updateMembershipDates() {} } + const network = { getCharData() {}, processPlayer: 1, sendZoneEvent() {} } + const services = new Map([ + ["NotAnId", { player: { data: {} } }], + ["1a2-3b4c", { player }], + ["83f-419b", membership], + ["ab-cd", network] + ]) + const gameContainer = { _inversifyContainer: { _bindingDictionary: { _map: services } }, get: (id: unknown) => services.get(id) } + const singleton = { prodigy: { gameContainer } as any, game: { state: { states: new Map([["Boot", { _gameData: { pet: [] } }]]) } } } + class Singleton { static get instance() { return singleton } get prodigy() { return null } } + const constants: Record = { "GameConstants.Build.VERSION": "2026.18.1" } + return { player, membership, network, gameContainer, singleton, Singleton, constants } +} + +describe("discoverService", () => { + it("returns the first hex-id binding matching the shape", () => { + const g = makeGame() + // "NotAnId" also has a player but is not a hex service id, so it is skipped. + assert.equal(discoverService(g.gameContainer, (i) => "player" in i), g.gameContainer.get("1a2-3b4c")) + }) + it("returns null without a binding map", () => { + assert.equal(discoverService({}, () => true), null) + }) +}) + +describe("addConstantsApi", () => { + it("adds hidden Map-like accessors over the same object", () => { + const raw: Record = { "GameConstants.Debug.EDUCATION_ENABLED": true } + addConstantsApi(raw) + raw.set("GameConstants.Debug.EDUCATION_ENABLED", false) + assert.equal(raw["GameConstants.Debug.EDUCATION_ENABLED"], false) + assert.equal(raw.get("GameConstants.Debug.EDUCATION_ENABLED"), false) + assert.equal(raw.has("GameConstants.Debug.EDUCATION_ENABLED"), true) + assert.equal(raw.constants, raw) + assert.deepEqual(Object.keys(raw), ["GameConstants.Debug.EDUCATION_ENABLED"]) + }) +}) + +describe("createOriginApi", () => { + it("creates window._ and exposes instance, constants, player, network, gameData, membership", () => { + const g = makeGame() + const win: any = {} + createOriginApi({ singletonClass: g.Singleton, constants: g.constants }).ensure(win) + assert.equal(win._.instance, g.singleton) + assert.equal(win._.constants, g.constants) + assert.equal(win._.player, g.player) + assert.equal(win._.network, g.network) + assert.equal(win._.network.game, g.singleton.game) + assert.deepEqual(win._.gameData, { pet: [] }) + assert.equal(win._.membership, g.membership) + }) + + it("re-applies after window._ is replaced and keeps lodash's functions", () => { + const g = makeGame() + const win: any = {} + const api = createOriginApi({ singletonClass: g.Singleton, constants: g.constants }) + api.ensure(win) + const lodashFunctions = () => [] + const lodash: any = Object.assign(function lodash() {}, { functions: lodashFunctions, cloneDeep: (x: unknown) => x }) + win._ = lodash + api.ensure(win) + assert.equal(win._, lodash) + assert.equal(win._.instance, g.singleton) + assert.equal(win._.functions, lodashFunctions) + assert.equal(typeof win._.functions.setMembership, "function") + }) + + it("setMembership toggles and restores the original membership data", () => { + const g = makeGame() + const win: any = {} + createOriginApi({ singletonClass: g.Singleton, constants: g.constants }).ensure(win) + const original = g.membership._data + assert.equal(win._.functions.setMembership(true), true) + assert.equal((g.membership._data as any).active, true) + assert.equal(g.membership.hasFeatureAccess(), true) + assert.equal(g.player.unlocked, true) + assert.equal(win._.functions.setMembership(false), true) + assert.equal(g.membership._data, original) + assert.equal(g.membership.hasFeatureAccess(), false) + }) + + it("keeps the original membership snapshot across re-apply", () => { + const g = makeGame() + const win: any = {} + const api = createOriginApi({ singletonClass: g.Singleton, constants: g.constants }) + api.ensure(win) + const original = g.membership._data + win._.functions.setMembership(true) + win._ = Object.assign(function lodash() {}, { functions: () => [] }) + api.ensure(win) + win._.functions.setMembership(false) + assert.equal(g.membership._data, original) + }) + + it("isReady waits for prodigy and player", () => { + const g = makeGame() + const win: any = {} + const api = createOriginApi({ singletonClass: g.Singleton, constants: g.constants }) + const prodigy = g.singleton.prodigy + g.singleton.prodigy = null + api.ensure(win) + assert.equal(api.isReady(win), false) + g.singleton.prodigy = prodigy + assert.equal(api.isReady(win), true) + }) +}) + +describe("ready signal", () => { + it("resolves listeners registered before and after the signal", async () => { + const win: any = new EventTarget() + const early = whenOriginReady(win) + let events = 0 + win.addEventListener(READY_EVENT, () => events++) + markOriginReady(win) + markOriginReady(win) + await early + await whenOriginReady(win) + assert.equal(events, 1) + }) +}) From e8cf43cdabf92ecfd789ec549c57725de3019dc0 Mon Sep 17 00:00:00 2001 From: Alexey Fedorov Date: Thu, 24 Sep 2026 01:47:46 -0500 Subject: [PATCH 07/11] feat(extension): load Prodigy's own game.min.js with packaged runtime hooks Removes the onreset injection, bridge, game.min.js block and CSP strip. Co-Authored-By: Claude Opus 5.5 --- extension/background.ts | 177 +-------------------- extension/contents/origin-bridge.ts | 46 ------ extension/contents/prodigy.ts | 237 ---------------------------- extension/contents/runtime.ts | 76 +++++++++ 4 files changed, 81 insertions(+), 455 deletions(-) delete mode 100644 extension/contents/origin-bridge.ts delete mode 100644 extension/contents/prodigy.ts create mode 100644 extension/contents/runtime.ts diff --git a/extension/background.ts b/extension/background.ts index dc4f3b7..85a382e 100644 --- a/extension/background.ts +++ b/extension/background.ts @@ -1,57 +1,10 @@ -// Background service worker for Play Origin (Chromium MV3). +// Background service worker for Play Origin (Chrome Web Store build). // -// Responsibilities: -// 1. DNR rules: BLOCK original game.min.js + strip CSP/X-Frame-Options + -// redirect login background and logo. -// 2. Handle GET_PATCHED_BUNDLE messages from the ISOLATED-world bridge: -// fetch manifest.json (popup may override URL), check the cache, -// fetch + patch the original on miss, prepend the resolved menu-URL -// global, return the patched JS source. - -import { - MANIFEST_URL, - gameVersionFromUrl -} from "./lib/patch-urls" -import { - applyPatchRules, - wrapWithPrefixSuffix -} from "./lib/patches" -import { validateManifest, type Manifest } from "./lib/manifest" -import { - getCachedBundle, - setCachedBundle, - type CacheEntry, - type StorageLocalApi -} from "./lib/bundle-cache" +// Only job: register the DNR rules that swap Prodigy's login background and +// logo for Play Origin art. No script blocking, no header stripping, and no +// code fetching; the game runs its own game.min.js. const RULES: chrome.declarativeNetRequest.Rule[] = [ - { - id: 1, - priority: 1, - action: { type: chrome.declarativeNetRequest.RuleActionType.BLOCK }, - condition: { - urlFilter: "*://code.prodigygame.com/code/*/game.min.js*", - resourceTypes: [chrome.declarativeNetRequest.ResourceType.SCRIPT] - } - }, - { - id: 2, - priority: 1, - action: { - type: chrome.declarativeNetRequest.RuleActionType.MODIFY_HEADERS, - responseHeaders: [ - { header: "Content-Security-Policy", operation: chrome.declarativeNetRequest.HeaderOperation.REMOVE }, - { header: "X-Frame-Options", operation: chrome.declarativeNetRequest.HeaderOperation.REMOVE } - ] - }, - condition: { - urlFilter: "*://*.prodigygame.com/*", - resourceTypes: [ - chrome.declarativeNetRequest.ResourceType.MAIN_FRAME, - chrome.declarativeNetRequest.ResourceType.SUB_FRAME - ] - } - }, { id: 3, priority: 2, @@ -90,129 +43,9 @@ const RULES: chrome.declarativeNetRequest.Rule[] = [ chrome.runtime.onInstalled.addListener(async () => { const existing = await chrome.declarativeNetRequest.getDynamicRules() - const existingIds = existing.map((r) => r.id) await chrome.declarativeNetRequest.updateDynamicRules({ - removeRuleIds: existingIds, + removeRuleIds: existing.map((r) => r.id), addRules: RULES }) console.log("[Origin] DeclarativeNetRequest rules registered successfully") }) - -const readOverrides = async (): Promise<{ - manifestUrlOverride: string - guiUrlOverride: string -}> => { - const storage = chrome.storage.local as unknown as StorageLocalApi - const res = await storage.get(["originManifestUrl", "originGuiUrl"]) - const manifestUrlOverride = - typeof res.originManifestUrl === "string" ? res.originManifestUrl : "" - const guiUrlOverride = - typeof res.originGuiUrl === "string" ? res.originGuiUrl : "" - return { manifestUrlOverride, guiUrlOverride } -} - -const fetchManifest = async (url: string): Promise => { - const r = await fetch(url, { cache: "default" }) - if (!r.ok) throw new Error(`manifest.json HTTP ${r.status}`) - const json = (await r.json()) as unknown - return validateManifest(json) -} - -const fetchOriginal = async (url: string): Promise => { - const r = await fetch(url, { cache: "default" }) - if (!r.ok) throw new Error(`original game.min.js HTTP ${r.status} for ${url}`) - const body = await r.text() - if (body.length < 1000) { - throw new Error(`original game.min.js suspiciously small (${body.length} bytes)`) - } - return body -} - -// Returns the wrapped patched bundle (prefix + patched + suffix) WITHOUT the -// menu-URL global prepended. The menu URL is resolved per-request and -// prepended at the call site so popup changes don't invalidate the cache. -const getOrBuildWrappedBundle = async ( - originalUrl: string, - manifest: Manifest -): Promise => { - const storage = chrome.storage.local as unknown as StorageLocalApi - const gameClientVersion = gameVersionFromUrl(originalUrl) - if (!gameClientVersion) throw new Error(`unparseable originalUrl: ${originalUrl}`) - - const cached = await getCachedBundle(storage) - if ( - cached && - cached.gameClientVersion === gameClientVersion && - cached.manifestHash === manifest.hash - ) { - console.log( - `[Origin] cache HIT for ${gameClientVersion} (hash=${manifest.hash})` - ) - return cached.patchedBundle - } - - console.log( - `[Origin] cache MISS for ${gameClientVersion} (hash=${manifest.hash}) — building` - ) - const original = await fetchOriginal(originalUrl) - const { output: patchedCore, perRuleCounts } = applyPatchRules(original, manifest.rules) - for (const rule of manifest.rules) { - console.log(`[Origin] rule "${rule.id}" matched ${perRuleCounts[rule.id] ?? 0}x`) - } - const wrapped = wrapWithPrefixSuffix(patchedCore, manifest.prefix, manifest.suffix) - - const degradedRules = manifest.rules.filter(r => (perRuleCounts[r.id] ?? 0) < r.minMatches) - if (degradedRules.length > 0) { - for (const r of degradedRules) { - console.warn(`[Origin] DEGRADED: rule "${r.id}" matched ${perRuleCounts[r.id] ?? 0}x (expected ≥${r.minMatches}) — skipping cache`) - } - return wrapped - } - - const entry: CacheEntry = { - gameClientVersion, - manifestHash: manifest.hash, - patchedBundle: wrapped, - storedAt: Date.now() - } - await setCachedBundle(storage, entry) - console.log(`[Origin] cache STORED for ${gameClientVersion}`) - return wrapped -} - -const getOrBuildPatchedBundle = async (originalUrl: string): Promise => { - const { manifestUrlOverride, guiUrlOverride } = await readOverrides() - const manifestUrl = manifestUrlOverride || MANIFEST_URL - if (manifestUrlOverride) { - console.log(`[Origin] using manifest URL override: ${manifestUrl}`) - } - - const manifest = await fetchManifest(manifestUrl) - const wrapped = await getOrBuildWrappedBundle(originalUrl, manifest) - - const resolvedMenuUrl = guiUrlOverride || manifest.defaultMenuUrl - if (guiUrlOverride) { - console.log(`[Origin] using menu URL override: ${resolvedMenuUrl}`) - } - const menuUrlPrefix = - `globalThis.__ORIGIN_MENU_URL__=${JSON.stringify(resolvedMenuUrl)};\n` - return menuUrlPrefix + wrapped -} - -chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => { - if (msg?.type !== "GET_PATCHED_BUNDLE" || typeof msg.originalUrl !== "string") { - return false - } - getOrBuildPatchedBundle(msg.originalUrl) - .then((patchedBundle) => sendResponse({ ok: true, patchedBundle })) - .catch((err: unknown) => { - console.error("[Origin] GET_PATCHED_BUNDLE failed:", err) - sendResponse({ - ok: false, - error: err instanceof Error ? err.message : String(err) - }) - }) - return true -}) - -export {} diff --git a/extension/contents/origin-bridge.ts b/extension/contents/origin-bridge.ts deleted file mode 100644 index 0889db0..0000000 --- a/extension/contents/origin-bridge.ts +++ /dev/null @@ -1,46 +0,0 @@ -import type { PlasmoCSConfig } from "plasmo" - -/** - * Play Origin Bridge — ISOLATED-world content script. - * - * The MAIN-world script (contents/prodigy.ts) cannot call chrome.* APIs. - * It dispatches `__origin_patch_request__` on `document` with the captured - * game URL; this bridge forwards the request to the background service worker - * via chrome.runtime.sendMessage, then dispatches `__origin_patch_response__` - * back with the result. - * - * Default world is ISOLATED — leaving the `world:` field unset avoids the - * Parcel transformer rejecting it. - */ -export const config: PlasmoCSConfig = { - matches: ["https://math.prodigygame.com/*"], - run_at: "document_start" -} - -type RequestDetail = { originalUrl: string } -type ResponseDetail = - | { ok: true; patchedBundle: string } - | { ok: false; error: string } - -document.addEventListener("__origin_patch_request__", (e: Event) => { - const detail = (e as CustomEvent).detail - if (!detail || typeof detail.originalUrl !== "string") return - - chrome.runtime - .sendMessage({ type: "GET_PATCHED_BUNDLE", originalUrl: detail.originalUrl }) - .then((response: ResponseDetail) => { - document.dispatchEvent( - new CustomEvent("__origin_patch_response__", { detail: response }) - ) - }) - .catch((err: unknown) => { - const message = err instanceof Error ? err.message : String(err) - document.dispatchEvent( - new CustomEvent("__origin_patch_response__", { - detail: { ok: false, error: `bridge: ${message}` } - }) - ) - }) -}) - -console.log("[Origin] bridge active") diff --git a/extension/contents/prodigy.ts b/extension/contents/prodigy.ts deleted file mode 100644 index 8344d7d..0000000 --- a/extension/contents/prodigy.ts +++ /dev/null @@ -1,237 +0,0 @@ -import type { PlasmoCSConfig } from "plasmo" -import { isGameScriptSrc } from "../lib/patch-urls" -import { VERSION } from "../lib/version" - -export const config: PlasmoCSConfig = { - matches: ["https://math.prodigygame.com/*"], - run_at: "document_start", - world: "MAIN" -} - -declare global { - interface Window { - __ORIGIN_INJECTED__?: boolean - __ORIGIN_HANDLED__?: boolean - } -} - -// ─── Save originals ─── -const origAppendChild = Node.prototype.appendChild -const origInsertBefore = Node.prototype.insertBefore -const origAppend = Element.prototype.append -const origRemoveAttribute = Element.prototype.removeAttribute -const origSetAttribute = Element.prototype.setAttribute -const origGetAttribute = Element.prototype.getAttribute -const origCreateElement = Document.prototype.createElement - -// ─── Integrity (SRI) bypass ─── -function lockIntegrity(el: HTMLElement): void { - Object.defineProperty(el, "integrity", { - set() {}, - get() { return "" }, - configurable: true - }) -} - -Document.prototype.createElement = function (tagName: string, options?: ElementCreationOptions): HTMLElement { - const el = origCreateElement.call(this, tagName, options) as HTMLElement - const tag = tagName.toLowerCase() - if (tag === "script" || tag === "link") { - lockIntegrity(el) - } - return el -} - -Element.prototype.setAttribute = function (name: string, value: string) { - if (name === "integrity") return - return origSetAttribute.call(this, name, value) -} - -for (const Proto of [HTMLScriptElement.prototype, HTMLLinkElement.prototype]) { - Object.defineProperty(Proto, "integrity", { - set() {}, - get() { return "" }, - configurable: true - }) -} - -function stripIntegrity(node: Node): void { - if (node instanceof HTMLScriptElement || node instanceof HTMLLinkElement) { - if (origGetAttribute.call(node, "integrity")) { - origRemoveAttribute.call(node, "integrity") - } - } -} - -// ─── Bridge round-trip ─── - -type ResponseDetail = - | { ok: true; patchedBundle: string } - | { ok: false; error: string } - -const requestPatchedBundle = (originalUrl: string): Promise => { - return new Promise((resolve, reject) => { - const onResponse = (e: Event) => { - document.removeEventListener("__origin_patch_response__", onResponse) - const detail = (e as CustomEvent).detail - if (detail.ok) resolve(detail.patchedBundle) - else reject(new Error(detail.error || "patch failed")) - } - document.addEventListener("__origin_patch_response__", onResponse) - document.dispatchEvent( - new CustomEvent("__origin_patch_request__", { detail: { originalUrl } }) - ) - }) -} - -// ─── Game-script interception ─── - -function isInterceptableGameScript(node: Node): node is HTMLScriptElement { - if (!(node instanceof HTMLScriptElement)) return false - if (origGetAttribute.call(node, "data-origin") === "1") return false - const src = node.src || origGetAttribute.call(node, "src") || "" - return isGameScriptSrc(src) -} - -function captureSrc(node: HTMLScriptElement): string { - return node.src || origGetAttribute.call(node, "src") || "" -} - -function createNopScript(): HTMLScriptElement { - const nop = origCreateElement.call(document, "script") as HTMLScriptElement - lockIntegrity(nop) - origSetAttribute.call(nop, "data-origin", "1") - return nop -} - -function injectPatchedBundle(originalUrl: string): void { - if (window.__ORIGIN_HANDLED__) return - window.__ORIGIN_HANDLED__ = true - - console.log(`[Origin] requesting patched bundle (origin=${originalUrl})`) - requestPatchedBundle(originalUrl) - .then((js) => { - // Prepend `var URL=window.URL;` to shadow document.URL (a string) so - // `new URL(...)` calls inside the patched bundle resolve to the URL class. - const payload = "var URL=window.URL;\n" + js - document.documentElement.setAttribute("onreset", payload) - document.documentElement.dispatchEvent(new CustomEvent("reset")) - document.documentElement.removeAttribute("onreset") - console.log("[Origin] patched bundle injected via onreset") - }) - .catch((e) => { - console.error("[Origin] failed to obtain patched bundle:", e) - }) -} - -// ─── Override script-insertion APIs ─── - -Node.prototype.appendChild = function (child: T): T { - if (isInterceptableGameScript(child)) { - const originalUrl = captureSrc(child as unknown as HTMLScriptElement) - injectPatchedBundle(originalUrl) - return origAppendChild.call(this, createNopScript()) as unknown as T - } - stripIntegrity(child) - return origAppendChild.call(this, child) as T -} - -Node.prototype.insertBefore = function (newNode: T, refNode: Node | null): T { - if (isInterceptableGameScript(newNode)) { - const originalUrl = captureSrc(newNode as unknown as HTMLScriptElement) - injectPatchedBundle(originalUrl) - return origInsertBefore.call(this, createNopScript(), refNode) as unknown as T - } - stripIntegrity(newNode) - return origInsertBefore.call(this, newNode, refNode) as T -} - -Element.prototype.append = function (...nodes: (Node | string)[]) { - const processed = nodes.map((node) => { - if (node instanceof Node && isInterceptableGameScript(node)) { - const originalUrl = captureSrc(node as HTMLScriptElement) - injectPatchedBundle(originalUrl) - return createNopScript() - } - if (node instanceof Node) stripIntegrity(node) - return node - }) - return origAppend.apply(this, processed) -} - -// ─── MutationObserver: catch parser-added script tags + preloads ─── - -function handleParserAddedGameScript(script: HTMLScriptElement): void { - const originalUrl = captureSrc(script) - origSetAttribute.call(script, "data-origin", "1") - script.removeAttribute("src") - script.textContent = "" - injectPatchedBundle(originalUrl) -} - -const observer = new MutationObserver((mutations) => { - for (const mutation of mutations) { - for (const node of mutation.addedNodes) { - if (node instanceof HTMLScriptElement) { - if (origGetAttribute.call(node, "integrity")) { - origRemoveAttribute.call(node, "integrity") - } - if ( - origGetAttribute.call(node, "data-origin") !== "1" && - isGameScriptSrc(node.src || origGetAttribute.call(node, "src") || "") - ) { - handleParserAddedGameScript(node) - } - } else if (node instanceof HTMLLinkElement) { - if (origGetAttribute.call(node, "integrity")) { - origRemoveAttribute.call(node, "integrity") - } - const rel = (node.rel || "").toLowerCase() - if (rel === "preload" && isGameScriptSrc(node.href || "")) { - node.remove() - } - } - } - } -}) - -function scanExistingDom(): void { - const existing = document.querySelector( - 'script[src*="/code/"]:not([data-origin])' - ) - if (existing && isGameScriptSrc(existing.src)) { - handleParserAddedGameScript(existing) - } - - document - .querySelectorAll('link[rel="preload"]') - .forEach((link) => { - if (isGameScriptSrc(link.href)) link.remove() - }) - - document - .querySelectorAll("script[integrity], link[integrity]") - .forEach((el) => origRemoveAttribute.call(el, "integrity")) -} - -// ─── Init ─── -;(function main() { - if (window.__ORIGIN_INJECTED__) return - window.__ORIGIN_INJECTED__ = true - - const root = document.documentElement || document - observer.observe(root, { childList: true, subtree: true }) - - if (!document.documentElement) { - const earlyObserver = new MutationObserver(() => { - if (document.documentElement) { - earlyObserver.disconnect() - observer.observe(document.documentElement, { childList: true, subtree: true }) - } - }) - earlyObserver.observe(document, { childList: true }) - } - - scanExistingDom() - console.log(`[Origin] content script active (client-side patching v${VERSION})`) -})() diff --git a/extension/contents/runtime.ts b/extension/contents/runtime.ts new file mode 100644 index 0000000..9035f03 --- /dev/null +++ b/extension/contents/runtime.ts @@ -0,0 +1,76 @@ +import type { PlasmoCSConfig } from "plasmo" +import { createOriginApi } from "../lib/runtime/api" +import { + installAnswerQuestionActionBypass, + installOpenQuestionBypass, + installTowerTownBypass +} from "../lib/runtime/bypasses" +import { installModuleHook } from "../lib/runtime/modules" +import { markOriginReady } from "../lib/runtime/ready" +import { missingTargets, resolveTargets, type Targets } from "../lib/runtime/resolve" +import { VERSION } from "../lib/version" + +export const config: PlasmoCSConfig = { + matches: ["https://math.prodigygame.com/*"], + run_at: "document_start", + world: "MAIN" +} + +// Must run before game.min.js so every webpack export object is seen. +const exportsObjects = new Set() +installModuleHook(Object, exportsObjects) + +const TICK_MS = 500 +const GIVE_UP_MS = 120_000 +const startedAt = Date.now() + +let targets: Targets = {} +let api: ReturnType | undefined +let reportedMissing = false +const installed = new Set() +const getConstants = () => targets.constants + +const install = (name: string, run: () => boolean) => { + if (installed.has(name)) return + if (run()) { + installed.add(name) + console.log(`[Origin] hook installed: ${name}`) + } +} + +const tick = () => { + const searching = missingTargets(targets).length > 0 && Date.now() - startedAt < GIVE_UP_MS + if (searching) targets = resolveTargets(exportsObjects, targets) + + const { componentRegistry, baseActionClass, towerTownClass, singletonClass, constants } = targets + if (componentRegistry?.OpenQuestionInterface) { + install("OpenQuestionInterface.answerQuestion", () => + installOpenQuestionBypass(componentRegistry.OpenQuestionInterface, getConstants)) + } + if (baseActionClass) install("AnswerQuestion action", () => installAnswerQuestionActionBypass(baseActionClass, getConstants)) + if (towerTownClass) install("Tower Town questions", () => installTowerTownBypass(towerTownClass, getConstants)) + + if (singletonClass && constants) { + api ??= createOriginApi({ singletonClass, constants }) + api.ensure(window) + if (api.isReady(window)) markOriginReady(window) + } + + if (!searching && !reportedMissing) { + const missing = missingTargets(targets) + if (missing.length > 0) { + reportedMissing = true + console.warn(`[Origin] hook target missing: ${missing.join(", ")}`) + } + } +} + +setInterval(() => { + try { + tick() + } catch (e) { + console.error("[Origin] runtime tick failed:", e) + } +}, TICK_MS) + +console.log(`[Origin] packaged runtime active v${VERSION}`) From dd351b29acb814c77853ad15ea5dfc26ed913e33 Mon Sep 17 00:00:00 2001 From: Alexey Fedorov Date: Thu, 24 Sep 2026 13:04:54 -0500 Subject: [PATCH 08/11] feat: package originGUI into the Chrome extension, drop remote menu loading and evals Co-Authored-By: Claude Opus 5.5 --- .gitignore | 4 ++ extension/contents/menu.ts | 19 +++++++++ extension/package.json | 9 +++-- originGUI/build.mjs | 12 ++++++ originGUI/dist/bundle.js | 72 +++++++++++++++++----------------- originGUI/src/hacks/beta.ts | 30 -------------- originGUI/src/hacks/pets.ts | 3 +- originGUI/src/hacks/player.ts | 2 +- originGUI/src/hacks/utility.ts | 42 +------------------- originGUI/src/index.ts | 13 ------ 10 files changed, 79 insertions(+), 127 deletions(-) create mode 100644 extension/contents/menu.ts diff --git a/.gitignore b/.gitignore index aeac061..0674e47 100644 --- a/.gitignore +++ b/.gitignore @@ -67,3 +67,7 @@ extension/firefox/.plasmo/ .mcp.json .worktrees/ .superpowers/ + +# Generated menu module for the Chrome extension +originGUI/dist/menu.js +originGUI/dist/menu.d.ts diff --git a/extension/contents/menu.ts b/extension/contents/menu.ts new file mode 100644 index 0000000..dc0d2cd --- /dev/null +++ b/extension/contents/menu.ts @@ -0,0 +1,19 @@ +import type { PlasmoCSConfig } from "plasmo" +import startOriginMenu from "../../originGUI/dist/menu.js" +import { whenOriginReady } from "../lib/runtime/ready" + +export const config: PlasmoCSConfig = { + matches: ["https://math.prodigygame.com/*"], + run_at: "document_idle", + world: "MAIN" +} + +// originGUI reads window._.player at load, so start only once the game is ready. +whenOriginReady(window).then(() => { + try { + startOriginMenu() + console.log("[Origin] menu started") + } catch (e) { + console.error("[Origin] menu failed to start:", e) + } +}) diff --git a/extension/package.json b/extension/package.json index 9bab91f..8617cb2 100644 --- a/extension/package.json +++ b/extension/package.json @@ -4,13 +4,14 @@ "private": true, "description": "Plasmo-based Play Origin browser extension", "scripts": { - "dev": "plasmo dev", + "menu": "pnpm --dir ../originGUI build", + "dev": "pnpm run menu && plasmo dev", "dev:firefox": "plasmo dev --target=firefox-mv3", - "build": "plasmo build", + "build": "pnpm run menu && plasmo build", "build:firefox": "plasmo build --target=firefox-mv3", - "package": "plasmo package", + "package": "pnpm run menu && plasmo package", "package:firefox": "plasmo package --target=firefox-mv3", - "typecheck": "tsc --noEmit", + "typecheck": "pnpm run menu && tsc --noEmit", "test": "node --experimental-strip-types --test \"tests/**/*.test.ts\"" }, "dependencies": { diff --git a/originGUI/build.mjs b/originGUI/build.mjs index ac8c85d..4972264 100644 --- a/originGUI/build.mjs +++ b/originGUI/build.mjs @@ -10,6 +10,8 @@ const rootDir = path.dirname(fileURLToPath(import.meta.url)); const srcDir = path.join(rootDir, "src"); const distDir = path.join(rootDir, "dist"); const bundlePath = path.join(distDir, "bundle.js"); +const menuModulePath = path.join(distDir, "menu.js"); +const menuTypesPath = path.join(distDir, "menu.d.ts"); // Files intentionally excluded from auto-discovery (inert stubs / archived code) const EXCLUDED_FILES = new Set(["patched.ts", "patchedMods.ts"]); @@ -75,6 +77,14 @@ if (!style.parentNode) { }; } +// Wraps the IIFE bundle in a function so the Chrome extension can package the +// menu inside a content script and start it once the game is ready. +async function writeMenuModule () { + const bundle = await fs.promises.readFile(bundlePath, "utf8"); + await fs.promises.writeFile(menuModulePath, `// Generated by originGUI/build.mjs. Do not edit.\nexport default function startOriginMenu () {\n${bundle}\n}\n`); + await fs.promises.writeFile(menuTypesPath, "export default function startOriginMenu (): void;\n"); +} + function toImportPath (filePath) { return `./${path.relative(rootDir, filePath).split(path.sep).join("/")}`; } @@ -112,6 +122,8 @@ export async function buildBundle ({ mode = "production" } = {}) { plugins: [createScssPlugin()], logLevel: "info", }); + + await writeMenuModule(); } const isDirectRun = process.argv[1] === fileURLToPath(import.meta.url); diff --git a/originGUI/dist/bundle.js b/originGUI/dist/bundle.js index f02736b..f13cd93 100644 --- a/originGUI/dist/bundle.js +++ b/originGUI/dist/bundle.js @@ -1,4 +1,4 @@ -(()=>{var vs=Object.create;var en=Object.defineProperty;var ks=Object.getOwnPropertyDescriptor;var Cs=Object.getOwnPropertyNames;var Es=Object.getPrototypeOf,xs=Object.prototype.hasOwnProperty;var y=(t,e,n)=>()=>{if(n)throw n[0];try{return t&&(e=t(t=0)),e}catch(o){throw n=[o],o}};var mt=(t,e)=>()=>{try{return e||t((e={exports:{}}).exports,e),e.exports}catch(n){throw e=0,n}},Ss=(t,e)=>{for(var n in e)en(t,n,{get:e[n],enumerable:!0})},As=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Cs(e))!xs.call(t,r)&&r!==n&&en(t,r,{get:()=>e[r],enumerable:!(o=ks(e,r))||o.enumerable});return t};var wt=(t,e,n)=>(n=t!=null?vs(Es(t)):{},As(e||!t||!t.__esModule?en(n,"default",{value:t,enumerable:!0}):n,t));var G,Ke,Ge,gt=y(()=>{G=Object.create(null);G.open="0";G.close="1";G.ping="2";G.pong="3";G.message="4";G.upgrade="5";G.noop="6";Ke=Object.create(null);Object.keys(G).forEach(t=>{Ke[G[t]]=t});Ge={type:"error",data:"parser error"}});function oo(t){return t instanceof Uint8Array?t:t instanceof ArrayBuffer?new Uint8Array(t):new Uint8Array(t.buffer,t.byteOffset,t.byteLength)}function ao(t,e){if(ro&&t.data instanceof Blob)return t.data.arrayBuffer().then(oo).then(e);if(so&&(t.data instanceof ArrayBuffer||io(t.data)))return e(oo(t.data));Xe(t,!1,n=>{tn||(tn=new TextEncoder),e(tn.encode(n))})}var ro,so,io,Xe,no,tn,lo=y(()=>{gt();ro=typeof Blob=="function"||typeof Blob<"u"&&Object.prototype.toString.call(Blob)==="[object BlobConstructor]",so=typeof ArrayBuffer=="function",io=t=>typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView(t):t&&t.buffer instanceof ArrayBuffer,Xe=({type:t,data:e},n,o)=>ro&&e instanceof Blob?n?o(e):no(e,o):so&&(e instanceof ArrayBuffer||io(e))?n?o(e):no(new Blob([e]),o):o(G[t]+(e||"")),no=(t,e)=>{let n=new FileReader;return n.onload=function(){let o=n.result.split(",")[1];e("b"+(o||""))},n.readAsDataURL(t)}});var co,Je,uo,po=y(()=>{co="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",Je=typeof Uint8Array>"u"?[]:new Uint8Array(256);for(let t=0;t{let e=t.length*.75,n=t.length,o,r=0,s,l,u,p;t[t.length-1]==="="&&(e--,t[t.length-2]==="="&&e--);let C=new ArrayBuffer(e),B=new Uint8Array(C);for(o=0;o>4,B[r++]=(l&15)<<4|u>>2,B[r++]=(u&3)<<6|p&63;return C}});var Ts,Ze,_s,ho,fo=y(()=>{gt();po();Ts=typeof ArrayBuffer=="function",Ze=(t,e)=>{if(typeof t!="string")return{type:"message",data:ho(t,e)};let n=t.charAt(0);return n==="b"?{type:"message",data:_s(t.substring(1),e)}:Ke[n]?t.length>1?{type:Ke[n],data:t.substring(1)}:{type:Ke[n]}:Ge},_s=(t,e)=>{if(Ts){let n=uo(t);return ho(n,e)}else return{base64:!0,data:t}},ho=(t,e)=>e==="blob"?t instanceof Blob?t:new Blob([t]):t instanceof ArrayBuffer?t:t.buffer});function yo(){return new TransformStream({transform(t,e){ao(t,n=>{let o=n.length,r;if(o<126)r=new Uint8Array(1),new DataView(r.buffer).setUint8(0,o);else if(o<65536){r=new Uint8Array(3);let s=new DataView(r.buffer);s.setUint8(0,126),s.setUint16(1,o)}else{r=new Uint8Array(9);let s=new DataView(r.buffer);s.setUint8(0,127),s.setBigUint64(1,BigInt(o))}t.data&&typeof t.data!="string"&&(r[0]|=128),e.enqueue(r),e.enqueue(n)})}})}function yt(t){return t.reduce((e,n)=>e+n.length,0)}function bt(t,e){if(t[0].length===e)return t.shift();let n=new Uint8Array(e),o=0;for(let r=0;rMath.pow(2,21)-1){u.enqueue(Ge);break}r=B*Math.pow(2,32)+C.getUint32(4),o=3}else{if(yt(n)t){u.enqueue(Ge);break}}}})}var mo,wo,go,nn,on,Te=y(()=>{lo();fo();gt();mo="",wo=(t,e)=>{let n=t.length,o=new Array(n),r=0;t.forEach((s,l)=>{Xe(s,!1,u=>{o[l]=u,++r===n&&e(o.join(mo))})})},go=(t,e)=>{let n=t.split(mo),o=[];for(let r=0;r{E.prototype.on=E.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+t]=this._callbacks["$"+t]||[]).push(e),this};E.prototype.once=function(t,e){function n(){this.off(t,n),e.apply(this,arguments)}return n.fn=e,this.on(t,n),this};E.prototype.off=E.prototype.removeListener=E.prototype.removeAllListeners=E.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},arguments.length==0)return this._callbacks={},this;var n=this._callbacks["$"+t];if(!n)return this;if(arguments.length==1)return delete this._callbacks["$"+t],this;for(var o,r=0;r{te=typeof Promise=="function"&&typeof Promise.resolve=="function"?e=>Promise.resolve().then(e):(e,n)=>n(e,0),N=typeof self<"u"?self:typeof window<"u"?window:Function("return this")(),vo="arraybuffer"});function vt(t,...e){return e.reduce((n,o)=>(t.hasOwnProperty(o)&&(n[o]=t[o]),n),{})}function ne(t,e){e.useNativeTimers?(t.setTimeoutFn=Bs.bind(N),t.clearTimeoutFn=Is.bind(N)):(t.setTimeoutFn=N.setTimeout.bind(N),t.clearTimeoutFn=N.clearTimeout.bind(N))}function ko(t){return typeof t=="string"?Ls(t):Math.ceil((t.byteLength||t.size)*Ds)}function Ls(t){let e=0,n=0;for(let o=0,r=t.length;o=57344?n+=3:(o++,n+=4);return n}function kt(){return Date.now().toString(36).substring(3)+Math.random().toString(36).substring(2,5)}var Bs,Is,Ds,ge=y(()=>{we();Bs=N.setTimeout,Is=N.clearTimeout;Ds=1.33});function Co(t){let e="";for(let n in t)t.hasOwnProperty(n)&&(e.length&&(e+="&"),e+=encodeURIComponent(n)+"="+encodeURIComponent(t[n]));return e}function Eo(t){let e={},n=t.split("&");for(let o=0,r=n.length;o{});var Ct,oe,Qe=y(()=>{Te();me();ge();rn();Ct=class extends Error{constructor(e,n,o){super(e),this.description=n,this.context=o,this.type="TransportError"}},oe=class extends E{constructor(e){super(),this.writable=!1,ne(this,e),this.opts=e,this.query=e.query,this.socket=e.socket,this.supportsBinary=!e.forceBase64}onError(e,n,o){return super.emitReserved("error",new Ct(e,n,o)),this}open(){return this.readyState="opening",this.doOpen(),this}close(){return(this.readyState==="opening"||this.readyState==="open")&&(this.doClose(),this.onClose()),this}send(e){this.readyState==="open"&&this.write(e)}onOpen(){this.readyState="open",this.writable=!0,super.emitReserved("open")}onData(e){let n=Ze(e,this.socket.binaryType);this.onPacket(n)}onPacket(e){super.emitReserved("packet",e)}onClose(e){this.readyState="closed",super.emitReserved("close",e)}pause(e){}createUri(e,n={}){return e+"://"+this._hostname()+this._port()+this.opts.path+this._query(n)}_hostname(){let e=this.opts.hostname;return e.indexOf(":")===-1?e:"["+e+"]"}_port(){return this.opts.port&&(this.opts.secure&&Number(this.opts.port)!==443||!this.opts.secure&&Number(this.opts.port)!==80)?":"+this.opts.port:""}_query(e){let n=Co(e);return n.length?"?"+n:""}}});var et,sn=y(()=>{Qe();ge();Te();et=class extends oe{constructor(){super(...arguments),this._polling=!1}get name(){return"polling"}doOpen(){this._poll()}pause(e){this.readyState="pausing";let n=()=>{this.readyState="paused",e()};if(this._polling||!this.writable){let o=0;this._polling&&(o++,this.once("pollComplete",function(){--o||n()})),this.writable||(o++,this.once("drain",function(){--o||n()}))}else n()}_poll(){this._polling=!0,this.doPoll(),this.emitReserved("poll")}onData(e){let n=o=>{if(this.readyState==="opening"&&o.type==="open"&&this.onOpen(),o.type==="close")return this.onClose({description:"transport closed by the server"}),!1;this.onPacket(o)};go(e,this.socket.binaryType).forEach(n),this.readyState!=="closed"&&(this._polling=!1,this.emitReserved("pollComplete"),this.readyState==="open"&&this._poll())}doClose(){let e=()=>{this.write([{type:"close"}])};this.readyState==="open"?e():this.once("open",e)}write(e){this.writable=!1,wo(e,n=>{this.doWrite(n,()=>{this.writable=!0,this.emitReserved("drain")})})}uri(){let e=this.opts.secure?"https":"http",n=this.query||{};return this.opts.timestampRequests!==!1&&(n[this.opts.timestampParam]=kt()),!this.supportsBinary&&!n.sid&&(n.b64=1),this.createUri(e,n)}}});var xo,So,Ao=y(()=>{xo=!1;try{xo=typeof XMLHttpRequest<"u"&&"withCredentials"in new XMLHttpRequest}catch{}So=xo});function Os(){}function To(){for(let t in ce.requests)ce.requests.hasOwnProperty(t)&&ce.requests[t].abort()}function _o(t){let e=t.xdomain;try{if(typeof XMLHttpRequest<"u"&&(!e||So))return new XMLHttpRequest}catch{}if(!e)try{return new N[["Active"].concat("Object").join("X")]("Microsoft.XMLHTTP")}catch{}}var an,ce,Rs,ue,Et=y(()=>{sn();me();ge();we();Ao();an=class extends et{constructor(e){if(super(e),typeof location<"u"){let n=location.protocol==="https:",o=location.port;o||(o=n?"443":"80"),this.xd=typeof location<"u"&&e.hostname!==location.hostname||o!==e.port}}doWrite(e,n){let o=this.request({method:"POST",data:e});o.on("success",n),o.on("error",(r,s)=>{this.onError("xhr post error",r,s)})}doPoll(){let e=this.request();e.on("data",this.onData.bind(this)),e.on("error",(n,o)=>{this.onError("xhr poll error",n,o)}),this.pollXhr=e}},ce=class t extends E{constructor(e,n,o){super(),this.createRequest=e,ne(this,o),this._opts=o,this._method=o.method||"GET",this._uri=n,this._data=o.data!==void 0?o.data:null,this._create()}_create(){var e;let n=vt(this._opts,"agent","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","autoUnref");n.xdomain=!!this._opts.xd;let o=this._xhr=this.createRequest(n);try{o.open(this._method,this._uri,!0);try{if(this._opts.extraHeaders){o.setDisableHeaderCheck&&o.setDisableHeaderCheck(!0);for(let r in this._opts.extraHeaders)this._opts.extraHeaders.hasOwnProperty(r)&&o.setRequestHeader(r,this._opts.extraHeaders[r])}}catch{}if(this._method==="POST")try{o.setRequestHeader("Content-type","text/plain;charset=UTF-8")}catch{}try{o.setRequestHeader("Accept","*/*")}catch{}(e=this._opts.cookieJar)===null||e===void 0||e.addCookies(o),"withCredentials"in o&&(o.withCredentials=this._opts.withCredentials),this._opts.requestTimeout&&(o.timeout=this._opts.requestTimeout),o.onreadystatechange=()=>{var r;o.readyState===3&&((r=this._opts.cookieJar)===null||r===void 0||r.parseCookies(o.getResponseHeader("set-cookie"))),o.readyState===4&&(o.status===200||o.status===1223?this._onLoad():this.setTimeoutFn(()=>{this._onError(typeof o.status=="number"?o.status:0)},0))},o.send(this._data)}catch(r){this.setTimeoutFn(()=>{this._onError(r)},0);return}typeof document<"u"&&(this._index=t.requestsCount++,t.requests[this._index]=this)}_onError(e){this.emitReserved("error",e,this._xhr),this._cleanup(!0)}_cleanup(e){if(!(typeof this._xhr>"u"||this._xhr===null)){if(this._xhr.onreadystatechange=Os,e)try{this._xhr.abort()}catch{}typeof document<"u"&&delete t.requests[this._index],this._xhr=null}}_onLoad(){let e=this._xhr.responseText;e!==null&&(this.emitReserved("data",e),this.emitReserved("success"),this._cleanup())}abort(){this._cleanup()}};ce.requestsCount=0;ce.requests={};if(typeof document<"u"){if(typeof attachEvent=="function")attachEvent("onunload",To);else if(typeof addEventListener=="function"){let t="onpagehide"in N?"pagehide":"unload";addEventListener(t,To,!1)}}Rs=(function(){let t=_o({xdomain:!1});return t&&t.responseType!==null})(),ue=class extends an{constructor(e){super(e);let n=e&&e.forceBase64;this.supportsBinary=Rs&&!n}request(e={}){return Object.assign(e,{xd:this.xd},this.opts),new ce(_o,this.uri(),e)}}});var Po,cn,ln,de,xt=y(()=>{Qe();ge();Te();we();Po=typeof navigator<"u"&&typeof navigator.product=="string"&&navigator.product.toLowerCase()==="reactnative",cn=class extends oe{get name(){return"websocket"}doOpen(){let e=this.uri(),n=this.opts.protocols,o=Po?{}:vt(this.opts,"agent","perMessageDeflate","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","localAddress","protocolVersion","origin","maxPayload","family","checkServerIdentity");this.opts.extraHeaders&&(o.headers=this.opts.extraHeaders);try{this.ws=this.createSocket(e,n,o)}catch(r){return this.emitReserved("error",r)}this.ws.binaryType=this.socket.binaryType,this.addEventListeners()}addEventListeners(){this.ws.onopen=()=>{this.opts.autoUnref&&this.ws._socket.unref(),this.onOpen()},this.ws.onclose=e=>this.onClose({description:"websocket connection closed",context:e}),this.ws.onmessage=e=>this.onData(e.data),this.ws.onerror=e=>this.onError("websocket error",e)}write(e){this.writable=!1;for(let n=0;n{try{this.doWrite(o,s)}catch{}r&&te(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){typeof this.ws<"u"&&(this.ws.onerror=()=>{},this.ws.close(),this.ws=null)}uri(){let e=this.opts.secure?"wss":"ws",n=this.query||{};return this.opts.timestampRequests&&(n[this.opts.timestampParam]=kt()),this.supportsBinary||(n.b64=1),this.createUri(e,n)}},ln=N.WebSocket||N.MozWebSocket,de=class extends cn{createSocket(e,n,o){return Po?new ln(e,n,o):n?new ln(e,n):new ln(e)}doWrite(e,n){this.ws.send(n)}}});var _e,un=y(()=>{Qe();we();Te();_e=class extends oe{get name(){return"webtransport"}doOpen(){try{this._transport=new WebTransport(this.createUri("https"),this.opts.transportOptions[this.name])}catch(e){return this.emitReserved("error",e)}this._transport.closed.then(()=>{this.onClose()}).catch(e=>{this.onError("webtransport error",e)}),this._transport.ready.then(()=>{this._transport.createBidirectionalStream().then(e=>{let n=bo(Number.MAX_SAFE_INTEGER,this.socket.binaryType),o=e.readable.pipeThrough(n).getReader(),r=yo();r.readable.pipeTo(e.writable),this._writer=r.writable.getWriter();let s=()=>{o.read().then(({done:u,value:p})=>{u||(this.onPacket(p),s())}).catch(u=>{})};s();let l={type:"open"};this.query.sid&&(l.data=`{"sid":"${this.query.sid}"}`),this._writer.write(l).then(()=>this.onOpen())})})}write(e){this.writable=!1;for(let n=0;n{r&&te(()=>{this.writable=!0,this.emitReserved("drain")},this.setTimeoutFn)})}}doClose(){var e;(e=this._transport)===null||e===void 0||e.close()}}});var dn,pn=y(()=>{Et();xt();un();dn={websocket:de,webtransport:_e,polling:ue}});function Pe(t){if(t.length>8e3)throw"URI too long";let e=t,n=t.indexOf("["),o=t.indexOf("]");n!=-1&&o!=-1&&(t=t.substring(0,n)+t.substring(n,o).replace(/:/g,";")+t.substring(o,t.length));let r=Ns.exec(t||""),s={},l=14;for(;l--;)s[Ms[l]]=r[l]||"";return n!=-1&&o!=-1&&(s.source=e,s.host=s.host.substring(1,s.host.length-1).replace(/;/g,":"),s.authority=s.authority.replace("[","").replace("]","").replace(/;/g,":"),s.ipv6uri=!0),s.pathNames=$s(s,s.path),s.queryKey=qs(s,s.query),s}function $s(t,e){let n=/\/{2,9}/g,o=e.replace(n,"/").split("/");return(e.slice(0,1)=="/"||e.length===0)&&o.splice(0,1),e.slice(-1)=="/"&&o.splice(o.length-1,1),o}function qs(t,e){let n={};return e.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,function(o,r,s){r&&(n[r]=s)}),n}var Ns,Ms,hn=y(()=>{Ns=/^(?:(?![^:@\/?#]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@\/?#]*)(?::([^:@\/?#]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,Ms=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"]});var fn,St,ye,At,Be,mn=y(()=>{pn();ge();rn();hn();me();Te();we();fn=typeof addEventListener=="function"&&typeof removeEventListener=="function",St=[];fn&&addEventListener("offline",()=>{St.forEach(t=>t())},!1);ye=class t extends E{constructor(e,n){if(super(),this.binaryType=vo,this.writeBuffer=[],this._prevBufferLen=0,this._pingInterval=-1,this._pingTimeout=-1,this._maxPayload=-1,this._pingTimeoutTime=1/0,e&&typeof e=="object"&&(n=e,e=null),e){let o=Pe(e);n.hostname=o.host,n.secure=o.protocol==="https"||o.protocol==="wss",n.port=o.port,o.query&&(n.query=o.query)}else n.host&&(n.hostname=Pe(n.host).host);ne(this,n),this.secure=n.secure!=null?n.secure:typeof location<"u"&&location.protocol==="https:",n.hostname&&!n.port&&(n.port=this.secure?"443":"80"),this.hostname=n.hostname||(typeof location<"u"?location.hostname:"localhost"),this.port=n.port||(typeof location<"u"&&location.port?location.port:this.secure?"443":"80"),this.transports=[],this._transportsByName={},n.transports.forEach(o=>{let r=o.prototype.name;this.transports.push(r),this._transportsByName[r]=o}),this.opts=Object.assign({path:"/engine.io",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:"t",rememberUpgrade:!1,addTrailingSlash:!0,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!1},n),this.opts.path=this.opts.path.replace(/\/$/,"")+(this.opts.addTrailingSlash?"/":""),typeof this.opts.query=="string"&&(this.opts.query=Eo(this.opts.query)),fn&&(this.opts.closeOnBeforeunload&&(this._beforeunloadEventListener=()=>{this.transport&&(this.transport.removeAllListeners(),this.transport.close())},addEventListener("beforeunload",this._beforeunloadEventListener,!1)),this.hostname!=="localhost"&&(this._offlineEventListener=()=>{this._onClose("transport close",{description:"network connection lost"})},St.push(this._offlineEventListener))),this.opts.withCredentials&&(this._cookieJar=void 0),this._open()}createTransport(e){let n=Object.assign({},this.opts.query);n.EIO=on,n.transport=e,this.id&&(n.sid=this.id);let o=Object.assign({},this.opts,{query:n,socket:this,hostname:this.hostname,secure:this.secure,port:this.port},this.opts.transportOptions[e]);return new this._transportsByName[e](o)}_open(){if(this.transports.length===0){this.setTimeoutFn(()=>{this.emitReserved("error","No transports available")},0);return}let e=this.opts.rememberUpgrade&&t.priorWebsocketSuccess&&this.transports.indexOf("websocket")!==-1?"websocket":this.transports[0];this.readyState="opening";let n=this.createTransport(e);n.open(),this.setTransport(n)}setTransport(e){this.transport&&this.transport.removeAllListeners(),this.transport=e,e.on("drain",this._onDrain.bind(this)).on("packet",this._onPacket.bind(this)).on("error",this._onError.bind(this)).on("close",n=>this._onClose("transport close",n))}onOpen(){this.readyState="open",t.priorWebsocketSuccess=this.transport.name==="websocket",this.emitReserved("open"),this.flush()}_onPacket(e){if(this.readyState==="opening"||this.readyState==="open"||this.readyState==="closing")switch(this.emitReserved("packet",e),this.emitReserved("heartbeat"),e.type){case"open":this.onHandshake(JSON.parse(e.data));break;case"ping":this._sendPacket("pong"),this.emitReserved("ping"),this.emitReserved("pong"),this._resetPingTimeout();break;case"error":let n=new Error("server error");n.code=e.data,this._onError(n);break;case"message":this.emitReserved("data",e.data),this.emitReserved("message",e.data);break}}onHandshake(e){this.emitReserved("handshake",e),this.id=e.sid,this.transport.query.sid=e.sid,this._pingInterval=e.pingInterval,this._pingTimeout=e.pingTimeout,this._maxPayload=e.maxPayload,this.onOpen(),this.readyState!=="closed"&&this._resetPingTimeout()}_resetPingTimeout(){this.clearTimeoutFn(this._pingTimeoutTimer);let e=this._pingInterval+this._pingTimeout;this._pingTimeoutTime=Date.now()+e,this._pingTimeoutTimer=this.setTimeoutFn(()=>{this._onClose("ping timeout")},e),this.opts.autoUnref&&this._pingTimeoutTimer.unref()}_onDrain(){this.writeBuffer.splice(0,this._prevBufferLen),this._prevBufferLen=0,this.writeBuffer.length===0?this.emitReserved("drain"):this.flush()}flush(){if(this.readyState!=="closed"&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length){let e=this._getWritablePackets();this.transport.send(e),this._prevBufferLen=e.length,this.emitReserved("flush")}}_getWritablePackets(){if(!(this._maxPayload&&this.transport.name==="polling"&&this.writeBuffer.length>1))return this.writeBuffer;let n=1;for(let o=0;o0&&n>this._maxPayload)return this.writeBuffer.slice(0,o);n+=2}return this.writeBuffer}_hasPingExpired(){if(!this._pingTimeoutTime)return!0;let e=Date.now()>this._pingTimeoutTime;return e&&(this._pingTimeoutTime=0,te(()=>{this._onClose("ping timeout")},this.setTimeoutFn)),e}write(e,n,o){return this._sendPacket("message",e,n,o),this}send(e,n,o){return this._sendPacket("message",e,n,o),this}_sendPacket(e,n,o,r){if(typeof n=="function"&&(r=n,n=void 0),typeof o=="function"&&(r=o,o=null),this.readyState==="closing"||this.readyState==="closed")return;o=o||{},o.compress=o.compress!==!1;let s={type:e,data:n,options:o};this.emitReserved("packetCreate",s),this.writeBuffer.push(s),r&&this.once("flush",r),this.flush()}close(){let e=()=>{this._onClose("forced close"),this.transport.close()},n=()=>{this.off("upgrade",n),this.off("upgradeError",n),e()},o=()=>{this.once("upgrade",n),this.once("upgradeError",n)};return(this.readyState==="opening"||this.readyState==="open")&&(this.readyState="closing",this.writeBuffer.length?this.once("drain",()=>{this.upgrading?o():e()}):this.upgrading?o():e()),this}_onError(e){if(t.priorWebsocketSuccess=!1,this.opts.tryAllTransports&&this.transports.length>1&&this.readyState==="opening")return this.transports.shift(),this._open();this.emitReserved("error",e),this._onClose("transport error",e)}_onClose(e,n){if(this.readyState==="opening"||this.readyState==="open"||this.readyState==="closing"){if(this.clearTimeoutFn(this._pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),fn&&(this._beforeunloadEventListener&&removeEventListener("beforeunload",this._beforeunloadEventListener,!1),this._offlineEventListener)){let o=St.indexOf(this._offlineEventListener);o!==-1&&St.splice(o,1)}this.readyState="closed",this.id=null,this.emitReserved("close",e,n),this.writeBuffer=[],this._prevBufferLen=0}}};ye.protocol=on;At=class extends ye{constructor(){super(...arguments),this._upgrades=[]}onOpen(){if(super.onOpen(),this.readyState==="open"&&this.opts.upgrade)for(let e=0;e{o||(n.send([{type:"ping",data:"probe"}]),n.once("packet",le=>{if(!o)if(le.type==="pong"&&le.data==="probe"){if(this.upgrading=!0,this.emitReserved("upgrading",n),!n)return;ye.priorWebsocketSuccess=n.name==="websocket",this.transport.pause(()=>{o||this.readyState!=="closed"&&(B(),this.setTransport(n),n.send([{type:"upgrade"}]),this.emitReserved("upgrade",n),n=null,this.upgrading=!1,this.flush())})}else{let je=new Error("probe error");je.transport=n.name,this.emitReserved("upgradeError",je)}}))};function s(){o||(o=!0,B(),n.close(),n=null)}let l=le=>{let je=new Error("probe error: "+le);je.transport=n.name,s(),this.emitReserved("upgradeError",je)};function u(){l("transport closed")}function p(){l("socket closed")}function C(le){n&&le.name!==n.name&&s()}let B=()=>{n.removeListener("open",r),n.removeListener("error",l),n.removeListener("close",u),this.off("close",p),this.off("upgrading",C)};n.once("open",r),n.once("error",l),n.once("close",u),this.once("close",p),this.once("upgrading",C),this._upgrades.indexOf("webtransport")!==-1&&e!=="webtransport"?this.setTimeoutFn(()=>{o||n.open()},200):n.open()}onHandshake(e){this._upgrades=this._filterUpgrades(e.upgrades),super.onHandshake(e)}_filterUpgrades(e){let n=[];for(let o=0;odn[s]).filter(s=>!!s)),super(o?r:e,r)}}});var Bo=y(()=>{sn()});var Wc,Tt=y(()=>{mn();mn();Qe();pn();ge();hn();we();Bo();Et();Et();xt();xt();un();Wc=Be.protocol});function Io(t,e="",n){let o=t;n=n||typeof location<"u"&&location,t==null&&(t=n.protocol+"//"+n.host),typeof t=="string"&&(t.charAt(0)==="/"&&(t.charAt(1)==="/"?t=n.protocol+t:t=n.host+t),/^(https?|wss?):\/\//.test(t)||(typeof n<"u"?t=n.protocol+"//"+t:t="https://"+t),o=Pe(t)),o.port||(/^(http|ws)$/.test(o.protocol)?o.port="80":/^(http|ws)s$/.test(o.protocol)&&(o.port="443")),o.path=o.path||"/";let s=o.host.indexOf(":")!==-1?"["+o.host+"]":o.host;return o.id=o.protocol+"://"+s+":"+o.port+e,o.href=o.protocol+"://"+s+(n&&n.port===o.port?"":":"+o.port),o}var Do=y(()=>{Tt()});function nt(t){return Fs&&(t instanceof ArrayBuffer||Vs(t))||Us&&t instanceof Blob||zs&&t instanceof File}function tt(t,e){if(!t||typeof t!="object")return!1;if(Array.isArray(t)){for(let n=0,o=t.length;n{Fs=typeof ArrayBuffer=="function",Vs=t=>typeof ArrayBuffer.isView=="function"?ArrayBuffer.isView(t):t.buffer instanceof ArrayBuffer,Lo=Object.prototype.toString,Us=typeof Blob=="function"||typeof Blob<"u"&&Lo.call(Blob)==="[object BlobConstructor]",zs=typeof File=="function"||typeof File<"u"&&Lo.call(File)==="[object FileConstructor]"});function Oo(t){let e=[],n=t.data,o=t;return o.data=_t(n,e),o.attachments=e.length,{packet:o,buffers:e}}function _t(t,e,n){if(!t)return t;if(nt(t)){let o={_placeholder:!0,num:e.length};return e.push(t),o}else if(Array.isArray(t)){let o=new Array(t.length);for(let r=0;r=0&&t.num{wn()});var kn={};Ss(kn,{Decoder:()=>bn,Encoder:()=>yn,PacketType:()=>g,isPacketValid:()=>Ks,protocol:()=>$o});function Ws(t){return typeof t=="string"}function Ys(t){return t===void 0||qo(t)}function Pt(t){return Object.prototype.toString.call(t)==="[object Object]"}function js(t,e){switch(t){case g.CONNECT:return e===void 0||Pt(e);case g.DISCONNECT:return e===void 0;case g.EVENT:return Array.isArray(e)&&(typeof e[0]=="number"||typeof e[0]=="string"&&Mo.indexOf(e[0])===-1);case g.ACK:return Array.isArray(e);case g.CONNECT_ERROR:return typeof e=="string"||Pt(e);default:return!1}}function Ks(t){return Ws(t.nsp)&&Ys(t.id)&&js(t.type,t.data)}var Mo,$o,g,yn,bn,vn,qo,Bt=y(()=>{me();No();wn();Mo=["connect","connect_error","disconnect","disconnecting","newListener","removeListener"],$o=5;(function(t){t[t.CONNECT=0]="CONNECT",t[t.DISCONNECT=1]="DISCONNECT",t[t.EVENT=2]="EVENT",t[t.ACK=3]="ACK",t[t.CONNECT_ERROR=4]="CONNECT_ERROR",t[t.BINARY_EVENT=5]="BINARY_EVENT",t[t.BINARY_ACK=6]="BINARY_ACK"})(g||(g={}));yn=class{constructor(e){this.replacer=e}encode(e){return(e.type===g.EVENT||e.type===g.ACK)&&tt(e)?this.encodeAsBinary({type:e.type===g.EVENT?g.BINARY_EVENT:g.BINARY_ACK,nsp:e.nsp,data:e.data,id:e.id}):[this.encodeAsString(e)]}encodeAsString(e){let n=""+e.type;return(e.type===g.BINARY_EVENT||e.type===g.BINARY_ACK)&&(n+=e.attachments+"-"),e.nsp&&e.nsp!=="/"&&(n+=e.nsp+","),e.id!=null&&(n+=e.id),e.data!=null&&(n+=JSON.stringify(e.data,this.replacer)),n}encodeAsBinary(e){let n=Oo(e),o=this.encodeAsString(n.packet),r=n.buffers;return r.unshift(o),r}},bn=class t extends E{constructor(e){super(),this.opts=Object.assign({reviver:void 0,maxAttachments:10},typeof e=="function"?{reviver:e}:e)}add(e){let n;if(typeof e=="string"){if(this.reconstructor)throw new Error("got plaintext data when reconstructing a packet");n=this.decodeString(e);let o=n.type===g.BINARY_EVENT;o||n.type===g.BINARY_ACK?(n.type=o?g.EVENT:g.ACK,this.reconstructor=new vn(n)):super.emitReserved("decoded",n)}else if(nt(e)||e.base64)if(this.reconstructor)n=this.reconstructor.takeBinaryData(e),n&&(this.reconstructor=null,super.emitReserved("decoded",n));else throw new Error("got binary data when not reconstructing a packet");else throw new Error("Unknown type: "+e)}decodeString(e){let n=0,o={type:Number(e.charAt(0))};if(g[o.type]===void 0)throw new Error("unknown packet type "+o.type);if(o.type===g.BINARY_EVENT||o.type===g.BINARY_ACK){let s=n+1;for(;e.charAt(++n)!=="-"&&n!=e.length;);let l=e.substring(s,n);if(l!=Number(l)||e.charAt(n)!=="-")throw new Error("Illegal attachments");let u=Number(l);if(!qo(u)||u<1)throw new Error("Illegal attachments");if(u>this.opts.maxAttachments)throw new Error("too many attachments");o.attachments=u}if(e.charAt(n+1)==="/"){let s=n+1;for(;++n&&!(e.charAt(n)===","||n===e.length););o.nsp=e.substring(s,n)}else o.nsp="/";let r=e.charAt(n+1);if(r!==""&&Number(r)==r){let s=n+1;for(;++n;){let l=e.charAt(n);if(l==null||Number(l)!=l){--n;break}if(n===e.length)break}o.id=Number(e.substring(s,n+1))}if(e.charAt(++n)){let s=this.tryParse(e.substr(n));if(t.isPayloadValid(o.type,s))o.data=s;else throw new Error("invalid payload")}return o}tryParse(e){try{return JSON.parse(e,this.opts.reviver)}catch{return!1}}static isPayloadValid(e,n){switch(e){case g.CONNECT:return Pt(n);case g.DISCONNECT:return n===void 0;case g.CONNECT_ERROR:return typeof n=="string"||Pt(n);case g.EVENT:case g.BINARY_EVENT:return Array.isArray(n)&&(typeof n[0]=="number"||typeof n[0]=="string"&&Mo.indexOf(n[0])===-1);case g.ACK:case g.BINARY_ACK:return Array.isArray(n)}}destroy(){this.reconstructor&&(this.reconstructor.finishedReconstruction(),this.reconstructor=null)}},vn=class{constructor(e){this.packet=e,this.buffers=[],this.reconPack=e}takeBinaryData(e){if(this.buffers.push(e),this.buffers.length===this.reconPack.attachments){let n=Ro(this.reconPack,this.buffers);return this.finishedReconstruction(),n}return null}finishedReconstruction(){this.reconPack=null,this.buffers=[]}};qo=Number.isInteger||function(t){return typeof t=="number"&&isFinite(t)&&Math.floor(t)===t}});function F(t,e,n){return t.on(e,n),function(){t.off(e,n)}}var Cn=y(()=>{});var Gs,Ie,En=y(()=>{Bt();Cn();me();Gs=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1}),Ie=class extends E{constructor(e,n,o){super(),this.connected=!1,this.recovered=!1,this.receiveBuffer=[],this.sendBuffer=[],this._queue=[],this._queueSeq=0,this.ids=0,this.acks={},this.flags={},this.io=e,this.nsp=n,o&&o.auth&&(this.auth=o.auth),this._opts=Object.assign({},o),this.io._autoConnect&&this.open()}get disconnected(){return!this.connected}subEvents(){if(this.subs)return;let e=this.io;this.subs=[F(e,"open",this.onopen.bind(this)),F(e,"packet",this.onpacket.bind(this)),F(e,"error",this.onerror.bind(this)),F(e,"close",this.onclose.bind(this))]}get active(){return!!this.subs}connect(){return this.connected?this:(this.subEvents(),this.io._reconnecting||this.io.open(),this.io._readyState==="open"&&this.onopen(),this)}open(){return this.connect()}send(...e){return e.unshift("message"),this.emit.apply(this,e),this}emit(e,...n){var o,r,s;if(Gs.hasOwnProperty(e))throw new Error('"'+e.toString()+'" is a reserved event name');if(n.unshift(e),this._opts.retries&&!this.flags.fromQueue&&!this.flags.volatile)return this._addToQueue(n),this;let l={type:g.EVENT,data:n};if(l.options={},l.options.compress=this.flags.compress!==!1,typeof n[n.length-1]=="function"){let B=this.ids++,le=n.pop();this._registerAckCallback(B,le),l.id=B}let u=(r=(o=this.io.engine)===null||o===void 0?void 0:o.transport)===null||r===void 0?void 0:r.writable,p=this.connected&&!(!((s=this.io.engine)===null||s===void 0)&&s._hasPingExpired());return this.flags.volatile&&!u||(p?(this.notifyOutgoingListeners(l),this.packet(l)):this.sendBuffer.push(l)),this.flags={},this}_registerAckCallback(e,n){var o;let r=(o=this.flags.timeout)!==null&&o!==void 0?o:this._opts.ackTimeout;if(r===void 0){this.acks[e]=n;return}let s=this.io.setTimeoutFn(()=>{delete this.acks[e];for(let u=0;u{this.io.clearTimeoutFn(s),n.apply(this,u)};l.withError=!0,this.acks[e]=l}emitWithAck(e,...n){return new Promise((o,r)=>{let s=(l,u)=>l?r(l):o(u);s.withError=!0,n.push(s),this.emit(e,...n)})}_addToQueue(e){let n;typeof e[e.length-1]=="function"&&(n=e.pop());let o={id:this._queueSeq++,tryCount:0,pending:!1,args:e,flags:Object.assign({fromQueue:!0},this.flags)};e.push((r,...s)=>(this._queue[0],r!==null?o.tryCount>this._opts.retries&&(this._queue.shift(),n&&n(r)):(this._queue.shift(),n&&n(null,...s)),o.pending=!1,this._drainQueue())),this._queue.push(o),this._drainQueue()}_drainQueue(e=!1){if(!this.connected||this._queue.length===0)return;let n=this._queue[0];n.pending&&!e||(n.pending=!0,n.tryCount++,this.flags=n.flags,this.emit.apply(this,n.args))}packet(e){e.nsp=this.nsp,this.io._packet(e)}onopen(){typeof this.auth=="function"?this.auth(e=>{this._sendConnectPacket(e)}):this._sendConnectPacket(this.auth)}_sendConnectPacket(e){this.packet({type:g.CONNECT,data:this._pid?Object.assign({pid:this._pid,offset:this._lastOffset},e):e})}onerror(e){this.connected||this.emitReserved("connect_error",e)}onclose(e,n){this.connected=!1,delete this.id,this.emitReserved("disconnect",e,n),this._clearAcks()}_clearAcks(){Object.keys(this.acks).forEach(e=>{if(!this.sendBuffer.some(o=>String(o.id)===e)){let o=this.acks[e];delete this.acks[e],o.withError&&o.call(this,new Error("socket has been disconnected"))}})}onpacket(e){if(e.nsp===this.nsp)switch(e.type){case g.CONNECT:e.data&&e.data.sid?this.onconnect(e.data.sid,e.data.pid):this.emitReserved("connect_error",new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)"));break;case g.EVENT:case g.BINARY_EVENT:this.onevent(e);break;case g.ACK:case g.BINARY_ACK:this.onack(e);break;case g.DISCONNECT:this.ondisconnect();break;case g.CONNECT_ERROR:this.destroy();let o=new Error(e.data.message);o.data=e.data.data,this.emitReserved("connect_error",o);break}}onevent(e){let n=e.data||[];e.id!=null&&n.push(this.ack(e.id)),this.connected?this.emitEvent(n):this.receiveBuffer.push(Object.freeze(n))}emitEvent(e){if(this._anyListeners&&this._anyListeners.length){let n=this._anyListeners.slice();for(let o of n)o.apply(this,e)}super.emit.apply(this,e),this._pid&&e.length&&typeof e[e.length-1]=="string"&&(this._lastOffset=e[e.length-1])}ack(e){let n=this,o=!1;return function(...r){o||(o=!0,n.packet({type:g.ACK,id:e,data:r}))}}onack(e){let n=this.acks[e.id];typeof n=="function"&&(delete this.acks[e.id],n.withError&&e.data.unshift(null),n.apply(this,e.data))}onconnect(e,n){this.id=e,this.recovered=n&&this._pid===n,this._pid=n,this.connected=!0,this.emitBuffered(),this._drainQueue(!0),this.emitReserved("connect")}emitBuffered(){this.receiveBuffer.forEach(e=>this.emitEvent(e)),this.receiveBuffer=[],this.sendBuffer.forEach(e=>{this.notifyOutgoingListeners(e),this.packet(e)}),this.sendBuffer=[]}ondisconnect(){this.destroy(),this.onclose("io server disconnect")}destroy(){this.subs&&(this.subs.forEach(e=>e()),this.subs=void 0),this.io._destroy(this)}disconnect(){return this.connected&&this.packet({type:g.DISCONNECT}),this.destroy(),this.connected&&this.onclose("io client disconnect"),this}close(){return this.disconnect()}compress(e){return this.flags.compress=e,this}get volatile(){return this.flags.volatile=!0,this}timeout(e){return this.flags.timeout=e,this}onAny(e){return this._anyListeners=this._anyListeners||[],this._anyListeners.push(e),this}prependAny(e){return this._anyListeners=this._anyListeners||[],this._anyListeners.unshift(e),this}offAny(e){if(!this._anyListeners)return this;if(e){let n=this._anyListeners;for(let o=0;o0&&t.jitter<=1?t.jitter:0,this.attempts=0}var Ho=y(()=>{be.prototype.duration=function(){var t=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),n=Math.floor(e*this.jitter*t);t=(Math.floor(e*10)&1)==0?t-n:t+n}return Math.min(t,this.max)|0};be.prototype.reset=function(){this.attempts=0};be.prototype.setMin=function(t){this.ms=t};be.prototype.setMax=function(t){this.max=t};be.prototype.setJitter=function(t){this.jitter=t}});var De,Fo=y(()=>{Tt();En();Bt();Cn();Ho();me();De=class extends E{constructor(e,n){var o;super(),this.nsps={},this.subs=[],e&&typeof e=="object"&&(n=e,e=void 0),n=n||{},n.path=n.path||"/socket.io",this.opts=n,ne(this,n),this.reconnection(n.reconnection!==!1),this.reconnectionAttempts(n.reconnectionAttempts||1/0),this.reconnectionDelay(n.reconnectionDelay||1e3),this.reconnectionDelayMax(n.reconnectionDelayMax||5e3),this.randomizationFactor((o=n.randomizationFactor)!==null&&o!==void 0?o:.5),this.backoff=new be({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(n.timeout==null?2e4:n.timeout),this._readyState="closed",this.uri=e;let r=n.parser||kn;this.encoder=new r.Encoder,this.decoder=new r.Decoder,this._autoConnect=n.autoConnect!==!1,this._autoConnect&&this.open()}reconnection(e){return arguments.length?(this._reconnection=!!e,e||(this.skipReconnect=!0),this):this._reconnection}reconnectionAttempts(e){return e===void 0?this._reconnectionAttempts:(this._reconnectionAttempts=e,this)}reconnectionDelay(e){var n;return e===void 0?this._reconnectionDelay:(this._reconnectionDelay=e,(n=this.backoff)===null||n===void 0||n.setMin(e),this)}randomizationFactor(e){var n;return e===void 0?this._randomizationFactor:(this._randomizationFactor=e,(n=this.backoff)===null||n===void 0||n.setJitter(e),this)}reconnectionDelayMax(e){var n;return e===void 0?this._reconnectionDelayMax:(this._reconnectionDelayMax=e,(n=this.backoff)===null||n===void 0||n.setMax(e),this)}timeout(e){return arguments.length?(this._timeout=e,this):this._timeout}maybeReconnectOnOpen(){!this._reconnecting&&this._reconnection&&this.backoff.attempts===0&&this.reconnect()}open(e){if(~this._readyState.indexOf("open"))return this;this.engine=new Be(this.uri,this.opts);let n=this.engine,o=this;this._readyState="opening",this.skipReconnect=!1;let r=F(n,"open",function(){o.onopen(),e&&e()}),s=u=>{this.cleanup(),this._readyState="closed",this.emitReserved("error",u),e?e(u):this.maybeReconnectOnOpen()},l=F(n,"error",s);if(this._timeout!==!1){let u=this._timeout,p=this.setTimeoutFn(()=>{r(),s(new Error("timeout")),n.close()},u);this.opts.autoUnref&&p.unref(),this.subs.push(()=>{this.clearTimeoutFn(p)})}return this.subs.push(r),this.subs.push(l),this}connect(e){return this.open(e)}onopen(){this.cleanup(),this._readyState="open",this.emitReserved("open");let e=this.engine;this.subs.push(F(e,"ping",this.onping.bind(this)),F(e,"data",this.ondata.bind(this)),F(e,"error",this.onerror.bind(this)),F(e,"close",this.onclose.bind(this)),F(this.decoder,"decoded",this.ondecoded.bind(this)))}onping(){this.emitReserved("ping")}ondata(e){try{this.decoder.add(e)}catch(n){this.onclose("parse error",n)}}ondecoded(e){te(()=>{this.emitReserved("packet",e)},this.setTimeoutFn)}onerror(e){this.emitReserved("error",e)}socket(e,n){let o=this.nsps[e];return o?this._autoConnect&&!o.active&&o.connect():(o=new Ie(this,e,n),this.nsps[e]=o),o}_destroy(e){let n=Object.keys(this.nsps);for(let o of n)if(this.nsps[o].active)return;this._close()}_packet(e){let n=this.encoder.encode(e);for(let o=0;oe()),this.subs.length=0,this.decoder.destroy()}_close(){this.skipReconnect=!0,this._reconnecting=!1,this.onclose("forced close")}disconnect(){return this._close()}onclose(e,n){var o;this.cleanup(),(o=this.engine)===null||o===void 0||o.close(),this.backoff.reset(),this._readyState="closed",this.emitReserved("close",e,n),this._reconnection&&!this.skipReconnect&&this.reconnect()}reconnect(){if(this._reconnecting||this.skipReconnect)return this;let e=this;if(this.backoff.attempts>=this._reconnectionAttempts)this.backoff.reset(),this.emitReserved("reconnect_failed"),this._reconnecting=!1;else{let n=this.backoff.duration();this._reconnecting=!0;let o=this.setTimeoutFn(()=>{e.skipReconnect||(this.emitReserved("reconnect_attempt",e.backoff.attempts),!e.skipReconnect&&e.open(r=>{r?(e._reconnecting=!1,e.reconnect(),this.emitReserved("reconnect_error",r)):e.onreconnect()}))},n);this.opts.autoUnref&&o.unref(),this.subs.push(()=>{this.clearTimeoutFn(o)})}}onreconnect(){let e=this.backoff.attempts;this._reconnecting=!1,this.backoff.reset(),this.emitReserved("reconnect",e)}}});function xn(t,e){typeof t=="object"&&(e=t,t=void 0),e=e||{};let n=Io(t,e.path||"/socket.io"),o=n.source,r=n.id,s=n.path,l=ot[r]&&s in ot[r].nsps,u=e.forceNew||e["force new connection"]||e.multiplex===!1||l,p;return u?p=new De(o,e):(ot[r]||(ot[r]=new De(o,e)),p=ot[r]),n.query&&!e.query&&(e.query=n.queryKey),p.socket(n.path,e)}var ot,Vo=y(()=>{Do();Fo();En();Bt();Tt();ot={};Object.assign(xn,{Manager:De,Socket:Ie,io:xn,connect:xn})});var Uo=y(()=>{"use strict";(()=>{let t=`@import url("https://fonts.googleapis.com/css?family=Arvo:400,700|Sen:400,700,800&display=swap&subset=latin-ext"); +(()=>{(()=>{let e=`@import url("https://fonts.googleapis.com/css?family=Arvo:400,700|Sen:400,700,800&display=swap&subset=latin-ext"); #game-wrapper { font-family: "Sen", sans-serif; } @@ -175,10 +175,7 @@ z-index: 2; background-color: rgba(0, 0, 0, 0.5); backdrop-filter: blur(5px); -}`,e="origingui-styles",n=document.getElementById(e)||document.createElement("style");n.id=e,n.textContent=t,n.parentNode||document.head.appendChild(n)})()});var d,i,zo,rt,Wo,It,pe,Iu,Dt,D,V,Xs,O,Yo,I=y(()=>{"use strict";d=window._,i=d.player,zo=()=>{try{return window._.instance?.game?.state?.getCurrentState()??null}catch{return null}},rt=new Proxy({},{get(t,e){let n=zo();return n?n[e]:void 0},set(t,e,n){let o=zo();return o&&(o[e]=n),!0}}),Wo=d.instance,It=Wo.game,pe=Wo.prodigy,Iu=d.instance.game.state.states.get("Boot").gameData,Dt=(t,e)=>d.gameData[t].find(n=>n.ID===e)??null,D=9e9,V=()=>{d.network.processPlayer=!0,d.player.forceSaveCharacter()},Xs="https://raw.githubusercontent.com/ProdigyPXP/ProdigyOrigin/master/originGUI/src/assets/",O=t=>`${Xs}${t}`,Yo={academy:O("academy.png"),bonfire_spire:O("bonfire_spire.png"),forest:O("forest.png"),shipwreck_shore:O("shipwreck_shore.png"),shiverchill:O("shiverchill.png"),skywatch:O("skywatch.png"),dyno:O("dyno.png"),elemental_guardian:O("elemental_guardian.png"),darktower:O("darktower.png"),earthtower:O("earthtower.png"),crystal_caverns:O("crystal_caverns.png"),archives:O("archives.png"),house:O("house.png"),toyzone:O("toyzone.png"),tower_town:O("tower_town.png"),lamplight:O("lamplight.png")}});function sr(t,e,n){if(typeof t=="function"?t===e:t.has(e))return arguments.length<3?e:n;throw new TypeError("Private element is not present on this object")}function Js(t,e){if(e.has(t))throw new TypeError("Cannot initialize the same private elements twice on an object")}function jo(t,e){return t.get(sr(t,e))}function Zs(t,e,n){Js(t,e),e.set(t,n)}function Qs(t,e,n){return t.set(sr(t,e),n),n}function xi(t,e,n){let o=J(),r=Se(),s=$e();!o||!r||!s||(Sn(o,"confirm",n),Sn(r,"deny",n),Sn(s,"cancel",n),Si(o,r,s,n),n.reverseButtons&&(n.toast?(t.insertBefore(s,o),t.insertBefore(r,o)):(t.insertBefore(s,e),t.insertBefore(r,e),t.insertBefore(o,e))))}function Si(t,e,n,o){if(!o.buttonsStyling){K([t,e,n],a.styled);return}b([t,e,n],a.styled),o.confirmButtonColor&&(t.style.backgroundColor=o.confirmButtonColor,b(t,a["default-outline"])),o.denyButtonColor&&(e.style.backgroundColor=o.denyButtonColor,b(e,a["default-outline"])),o.cancelButtonColor&&(n.style.backgroundColor=o.cancelButtonColor,b(n,a["default-outline"]))}function Sn(t,e,n){let o=In(e);lt(t,n[`show${o}Button`],"inline-block"),W(t,n[`${e}ButtonText`]||""),t.setAttribute("aria-label",n[`${e}ButtonAriaLabel`]||""),t.className=a[e],U(t,n,`${e}Button`)}function _i(t,e){typeof e=="string"?t.style.background=e:e||b([document.documentElement,document.body],a["no-backdrop"])}function Pi(t,e){e&&(e in a?b(t,a[e]):(M('The "position" parameter is not valid, defaulting to "center"'),b(t,a.center)))}function Bi(t,e){e&&b(t,a[`grow-${e}`])}function _r(t,e,n,o){Yt()?er(t,o):(ni(n).then(()=>er(t,o)),xr(m)),Tr?(e.setAttribute("style","display:none !important"),e.removeAttribute("class"),e.innerHTML=""):e.remove(),$n()&&(ga(),fa(),Ar()),ya()}function ya(){K([document.documentElement,document.body],[a.shown,a["height-auto"],a["no-backdrop"],a["toast-shown"]])}function fe(t){t=va(t);let e=Re.swalPromiseResolve.get(this),n=ba(this);this.isAwaitingPromise?t.isDismissed||(ut(this),e(t)):n&&e(t)}function Pr(t){let e=Re.swalPromiseReject.get(this);ut(this),e&&e(t)}function Ia(t,e,n){let o=he(t,a.select);if(!o)return;let r=(s,l,u)=>{let p=document.createElement("option");p.value=u,W(p,l),p.selected=Br(u,n.inputValue),s.appendChild(p)};e.forEach(s=>{let l=s[0],u=s[1];if(Array.isArray(u)){let p=document.createElement("optgroup");p.label=l,p.disabled=!1,o.appendChild(p),u.forEach(C=>r(p,C[1],C[0]))}else r(o,u,l)}),o.focus()}function Da(t,e,n){let o=he(t,a.radio);if(!o)return;e.forEach(s=>{let l=s[0],u=s[1],p=document.createElement("input"),C=document.createElement("label");p.type="radio",p.name=a.radio,p.value=l,Br(l,n.inputValue)&&(p.checked=!0);let B=document.createElement("span");W(B,u),B.className=a.label,C.appendChild(p),C.appendChild(B),o.appendChild(C)});let r=o.querySelectorAll("input");r.length&&r[0].focus()}function Ht(){let t=x.innerParams.get(this);if(!t)return;let e=x.domCache.get(this);R(e.loader),Yt()?t.icon&&L(Me()):Ma(e),K([e.popup,e.actions],a.loading),e.popup.removeAttribute("aria-busy"),e.popup.removeAttribute("data-loading"),e.confirmButton.disabled=!1,e.denyButton.disabled=!1,e.cancelButton.disabled=!1}function Lr(){let t=x.innerParams.get(this),e=x.domCache.get(this);return e?jt(e.popup,t.input):null}function Or(t,e,n){let o=x.domCache.get(t);e.forEach(r=>{o[r].disabled=n})}function Rr(t,e){let n=v();if(!(!n||!t))if(t.type==="radio"){let o=n.querySelectorAll(`[name="${a.radio}"]`);for(let r=0;r0&&arguments[0]!==void 0?arguments[0]:"data-swal-template";_n[t]=this,or||(document.body.addEventListener("click",ll),or=!0)}function Al(t){t.inputValidator||(t.input==="email"&&(t.inputValidator=rr.email),t.input==="url"&&(t.inputValidator=rr.url))}function Tl(t){(!t.target||typeof t.target=="string"&&!document.querySelector(t.target)||typeof t.target!="string"&&!t.target.appendChild)&&(M('Target parameter is not valid, defaulting to "body"'),t.target="body")}function _l(t){Al(t),t.showLoaderOnConfirm&&!t.preConfirm&&M(`showLoaderOnConfirm is set to true, but preConfirm is not defined. -showLoaderOnConfirm should be used together with preConfirm, see usage example: -https://sweetalert2.github.io/#ajax-request`),Tl(t),typeof t.title=="string"&&(t.title=t.title.split(` -`).join("
")),vi(t)}var ei,m,ti,ni,ir,oi,a,ri,Ot,ar,In,M,xe,Ko,si,lr,Ut,Dn,st,Ln,$,it,z,v,Me,ii,cr,On,ur,Rn,zt,J,$e,Se,ai,qe,at,dr,Wt,Nn,li,Mn,$n,Yt,ci,W,re,ui,U,jt,pr,hr,b,K,he,ke,L,R,qn,Go,lt,H,di,Xo,fr,Hn,pi,hi,fi,mi,ve,wi,gi,yi,bi,vi,Fn,ki,Ci,Ei,Ai,Ti,x,Ii,Di,Li,Oi,Ri,Ni,Vn,ct,mr,Rt,P,Mi,$i,qi,Jo,wr,Hi,Fi,Zo,Vi,Qo,Ui,Un,gr,yr,br,vr,zi,Wi,Nt,Mt,$t,kr,Yi,ji,Ki,Gi,Xi,Ji,Cr,Zi,Er,Qi,ea,He,xr,ta,Tn,Sr,na,oa,ra,sa,ia,aa,Re,la,Ar,Tr,ca,ua,da,pa,ha,fa,ma,Le,wa,ga,ba,ut,va,ka,Ca,er,Ne,Ea,xa,Sa,Aa,Ta,_a,Pa,Ba,qt,Br,La,Oa,Ra,Ir,Na,zn,tr,Dr,Wn,Ma,Oe,$a,qa,Ha,Vr,Ur,zr,Fa,Va,Ua,Wr,za,Wa,Kr,An,Ya,ja,Ka,Ga,Ft,Xa,Ja,Za,Qa,nr,el,ol,Gr,Xr,rl,sl,il,or,_n,ll,Pn,cl,ul,dl,pl,Bn,Jr,hl,fl,ml,wl,gl,yl,bl,vl,kl,Ce,Zr,Cl,Vt,El,xl,Sl,rr,X,Lt,_,Pl,Bl,Il,Dl,Ll,Ol,Rl,Nl,Ee,Yn=y(()=>{ei=100,m={},ti=()=>{m.previousActiveElement instanceof HTMLElement?(m.previousActiveElement.focus(),m.previousActiveElement=null):document.body&&document.body.focus()},ni=t=>new Promise(e=>{if(!t)return e();let n=window.scrollX,o=window.scrollY;m.restoreFocusTimeout=setTimeout(()=>{ti(),e()},ei),window.scrollTo(n,o)}),ir="swal2-",oi=["container","shown","height-auto","iosfix","popup","modal","no-backdrop","no-transition","toast","toast-shown","show","hide","close","title","html-container","actions","confirm","deny","cancel","default-outline","footer","icon","icon-content","image","input","file","range","select","radio","checkbox","label","textarea","inputerror","input-label","validation-message","progress-steps","active-progress-step","progress-step","progress-step-line","loader","loading","styled","top","top-start","top-end","top-left","top-right","center","center-start","center-end","center-left","center-right","bottom","bottom-start","bottom-end","bottom-left","bottom-right","grow-row","grow-column","grow-fullscreen","rtl","timer-progress-bar","timer-progress-bar-container","scrollbar-measure","icon-success","icon-warning","icon-info","icon-question","icon-error","draggable","dragging"],a=oi.reduce((t,e)=>(t[e]=ir+e,t),{}),ri=["success","warning","info","question","error"],Ot=ri.reduce((t,e)=>(t[e]=ir+e,t),{}),ar="SweetAlert2:",In=t=>t.charAt(0).toUpperCase()+t.slice(1),M=t=>{console.warn(`${ar} ${typeof t=="object"?t.join(" "):t}`)},xe=t=>{console.error(`${ar} ${t}`)},Ko=[],si=t=>{Ko.includes(t)||(Ko.push(t),M(t))},lr=function(t){let e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:null;si(`"${t}" is deprecated and will be removed in the next major release.${e?` Use "${e}" instead.`:""}`)},Ut=t=>typeof t=="function"?t():t,Dn=t=>t&&typeof t.toPromise=="function",st=t=>Dn(t)?t.toPromise():Promise.resolve(t),Ln=t=>t&&Promise.resolve(t)===t,$=()=>document.body.querySelector(`.${a.container}`),it=t=>{let e=$();return e?e.querySelector(t):null},z=t=>it(`.${t}`),v=()=>z(a.popup),Me=()=>z(a.icon),ii=()=>z(a["icon-content"]),cr=()=>z(a.title),On=()=>z(a["html-container"]),ur=()=>z(a.image),Rn=()=>z(a["progress-steps"]),zt=()=>z(a["validation-message"]),J=()=>it(`.${a.actions} .${a.confirm}`),$e=()=>it(`.${a.actions} .${a.cancel}`),Se=()=>it(`.${a.actions} .${a.deny}`),ai=()=>z(a["input-label"]),qe=()=>it(`.${a.loader}`),at=()=>z(a.actions),dr=()=>z(a.footer),Wt=()=>z(a["timer-progress-bar"]),Nn=()=>z(a.close),li=` +}`,t="origingui-styles",n=document.getElementById(t)||document.createElement("style");n.id=t,n.textContent=e,n.parentNode||document.head.appendChild(n)})();var c=window._,r=c.player,Ct=()=>{try{return window._.instance?.game?.state?.getCurrentState()??null}catch{return null}},he=new Proxy({},{get(e,t){let n=Ct();return n?n[t]:void 0},set(e,t,n){let o=Ct();return o&&(o[t]=n),!0}}),xt=c.instance,Ae=xt.game,V=xt.prodigy,$s=c.instance.game.state.states.get("Boot").gameData,Ie=(e,t)=>c.gameData[e].find(n=>n.ID===t)??null,P=9e9,$=()=>{c.network.processPlayer=!0,c.player.forceSaveCharacter()},jn="https://raw.githubusercontent.com/ProdigyPXP/ProdigyOrigin/master/originGUI/src/assets/",T=e=>`${jn}${e}`,Et={academy:T("academy.png"),bonfire_spire:T("bonfire_spire.png"),forest:T("forest.png"),shipwreck_shore:T("shipwreck_shore.png"),shiverchill:T("shiverchill.png"),skywatch:T("skywatch.png"),dyno:T("dyno.png"),elemental_guardian:T("elemental_guardian.png"),darktower:T("darktower.png"),earthtower:T("earthtower.png"),crystal_caverns:T("crystal_caverns.png"),archives:T("archives.png"),house:T("house.png"),toyzone:T("toyzone.png"),tower_town:T("tower_town.png"),lamplight:T("lamplight.png")};function _t(e,t,n){if(typeof e=="function"?e===t:e.has(t))return arguments.length<3?t:n;throw new TypeError("Private element is not present on this object")}function Wn(e,t){if(t.has(e))throw new TypeError("Cannot initialize the same private elements twice on an object")}function St(e,t){return e.get(_t(e,t))}function Yn(e,t,n){Wn(e,t),t.set(e,n)}function Vn(e,t,n){return e.set(_t(e,t),n),n}var Un=100,w={},Gn=()=>{w.previousActiveElement instanceof HTMLElement?(w.previousActiveElement.focus(),w.previousActiveElement=null):document.body&&document.body.focus()},Kn=e=>new Promise(t=>{if(!e)return t();let n=window.scrollX,o=window.scrollY;w.restoreFocusTimeout=setTimeout(()=>{Gn(),t()},Un),window.scrollTo(n,o)}),Nt="swal2-",Xn=["container","shown","height-auto","iosfix","popup","modal","no-backdrop","no-transition","toast","toast-shown","show","hide","close","title","html-container","actions","confirm","deny","cancel","default-outline","footer","icon","icon-content","image","input","file","range","select","radio","checkbox","label","textarea","inputerror","input-label","validation-message","progress-steps","active-progress-step","progress-step","progress-step-line","loader","loading","styled","top","top-start","top-end","top-left","top-right","center","center-start","center-end","center-left","center-right","bottom","bottom-start","bottom-end","bottom-left","bottom-right","grow-row","grow-column","grow-fullscreen","rtl","timer-progress-bar","timer-progress-bar-container","scrollbar-measure","icon-success","icon-warning","icon-info","icon-question","icon-error","draggable","dragging"],i=Xn.reduce((e,t)=>(e[t]=Nt+t,e),{}),Zn=["success","warning","info","question","error"],De=Zn.reduce((e,t)=>(e[t]=Nt+t,e),{}),Rt="SweetAlert2:",nt=e=>e.charAt(0).toUpperCase()+e.slice(1),B=e=>{console.warn(`${Rt} ${typeof e=="object"?e.join(" "):e}`)},te=e=>{console.error(`${Rt} ${e}`)},Pt=[],Jn=e=>{Pt.includes(e)||(Pt.push(e),B(e))},zt=function(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:null;Jn(`"${e}" is deprecated and will be removed in the next major release.${t?` Use "${t}" instead.`:""}`)},Re=e=>typeof e=="function"?e():e,ot=e=>e&&typeof e.toPromise=="function",ye=e=>ot(e)?e.toPromise():Promise.resolve(e),rt=e=>e&&Promise.resolve(e)===e,L=()=>document.body.querySelector(`.${i.container}`),be=e=>{let t=L();return t?t.querySelector(e):null},H=e=>be(`.${e}`),y=()=>H(i.popup),ie=()=>H(i.icon),Qn=()=>H(i["icon-content"]),qt=()=>H(i.title),st=()=>H(i["html-container"]),Ft=()=>H(i.image),at=()=>H(i["progress-steps"]),ze=()=>H(i["validation-message"]),z=()=>be(`.${i.actions} .${i.confirm}`),le=()=>be(`.${i.actions} .${i.cancel}`),ne=()=>be(`.${i.actions} .${i.deny}`),eo=()=>H(i["input-label"]),ce=()=>be(`.${i.loader}`),ve=()=>H(i.actions),jt=()=>H(i.footer),qe=()=>H(i["timer-progress-bar"]),it=()=>H(i.close),to=` a[href], area[href], input:not([disabled]), @@ -193,58 +190,61 @@ https://sweetalert2.github.io/#ajax-request`),Tl(t),typeof t.title=="string"&&(t audio[controls], video[controls], summary -`,Mn=()=>{let t=v();if(!t)return[];let e=t.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])'),n=Array.from(e).sort((s,l)=>{let u=parseInt(s.getAttribute("tabindex")||"0"),p=parseInt(l.getAttribute("tabindex")||"0");return u>p?1:us.getAttribute("tabindex")!=="-1");return[...new Set(n.concat(r))].filter(s=>H(s))},$n=()=>re(document.body,a.shown)&&!re(document.body,a["toast-shown"])&&!re(document.body,a["no-backdrop"]),Yt=()=>{let t=v();return t?re(t,a.toast):!1},ci=()=>{let t=v();return t?t.hasAttribute("data-loading"):!1},W=(t,e)=>{if(t.textContent="",e){let o=new DOMParser().parseFromString(e,"text/html"),r=o.querySelector("head");r&&Array.from(r.childNodes).forEach(l=>{t.appendChild(l)});let s=o.querySelector("body");s&&Array.from(s.childNodes).forEach(l=>{l instanceof HTMLVideoElement||l instanceof HTMLAudioElement?t.appendChild(l.cloneNode(!0)):t.appendChild(l)})}},re=(t,e)=>{if(!e)return!1;let n=e.split(/\s+/);for(let o=0;o{Array.from(t.classList).forEach(n=>{!Object.values(a).includes(n)&&!Object.values(Ot).includes(n)&&!Object.values(e.showClass||{}).includes(n)&&t.classList.remove(n)})},U=(t,e,n)=>{if(ui(t,e),!e.customClass)return;let o=e.customClass[n];if(o){if(typeof o!="string"&&!o.forEach){M(`Invalid type of customClass.${n}! Expected string or iterable object, got "${typeof o}"`);return}b(t,o)}},jt=(t,e)=>{if(!e)return null;switch(e){case"select":case"textarea":case"file":return t.querySelector(`.${a.popup} > .${a[e]}`);case"checkbox":return t.querySelector(`.${a.popup} > .${a.checkbox} input`);case"radio":return t.querySelector(`.${a.popup} > .${a.radio} input:checked`)||t.querySelector(`.${a.popup} > .${a.radio} input:first-child`);case"range":return t.querySelector(`.${a.popup} > .${a.range} input`);default:return t.querySelector(`.${a.popup} > .${a.input}`)}},pr=t=>{if(t.focus(),t.type!=="file"){let e=t.value;t.value="",t.value=e}},hr=(t,e,n)=>{!t||!e||(typeof e=="string"&&(e=e.split(/\s+/).filter(Boolean)),e.forEach(o=>{Array.isArray(t)?t.forEach(r=>{n?r.classList.add(o):r.classList.remove(o)}):n?t.classList.add(o):t.classList.remove(o)}))},b=(t,e)=>{hr(t,e,!0)},K=(t,e)=>{hr(t,e,!1)},he=(t,e)=>{let n=Array.from(t.children);for(let o=0;o{n===`${parseInt(n)}`&&(n=parseInt(n)),n||parseInt(n)===0?t.style.setProperty(e,typeof n=="number"?`${n}px`:n):t.style.removeProperty(e)},L=function(t){let e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"flex";t&&(t.style.display=e)},R=t=>{t&&(t.style.display="none")},qn=function(t){let e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"block";t&&new MutationObserver(()=>{lt(t,t.innerHTML,e)}).observe(t,{childList:!0,subtree:!0})},Go=(t,e,n,o)=>{let r=t.querySelector(e);r&&r.style.setProperty(n,o)},lt=function(t,e){let n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:"flex";e?L(t,n):R(t)},H=t=>!!(t&&(t.offsetWidth||t.offsetHeight||t.getClientRects().length)),di=()=>!H(J())&&!H(Se())&&!H($e()),Xo=t=>t.scrollHeight>t.clientHeight,fr=t=>{let e=window.getComputedStyle(t),n=parseFloat(e.getPropertyValue("animation-duration")||"0"),o=parseFloat(e.getPropertyValue("transition-duration")||"0");return n>0||o>0},Hn=function(t){let e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,n=Wt();n&&H(n)&&(e&&(n.style.transition="none",n.style.width="100%"),setTimeout(()=>{n.style.transition=`width ${t/1e3}s linear`,n.style.width="0%"},10))},pi=()=>{let t=Wt();if(!t)return;let e=parseInt(window.getComputedStyle(t).width);t.style.removeProperty("transition"),t.style.width="100%";let n=parseInt(window.getComputedStyle(t).width),o=e/n*100;t.style.width=`${o}%`},hi=()=>typeof window>"u"||typeof document>"u",fi=` -
- -
    -
    - -

    -
    - - -
    +`,lt=()=>{let e=y();if(!e)return[];let t=e.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])'),n=Array.from(t).sort((a,d)=>{let m=parseInt(a.getAttribute("tabindex")||"0"),f=parseInt(d.getAttribute("tabindex")||"0");return m>f?1:ma.getAttribute("tabindex")!=="-1");return[...new Set(n.concat(s))].filter(a=>M(a))},ct=()=>j(document.body,i.shown)&&!j(document.body,i["toast-shown"])&&!j(document.body,i["no-backdrop"]),Fe=()=>{let e=y();return e?j(e,i.toast):!1},no=()=>{let e=y();return e?e.hasAttribute("data-loading"):!1},_=(e,t)=>{if(e.textContent="",t){let o=new DOMParser().parseFromString(t,"text/html"),s=o.querySelector("head");s&&Array.from(s.childNodes).forEach(d=>{e.appendChild(d)});let a=o.querySelector("body");a&&Array.from(a.childNodes).forEach(d=>{d instanceof HTMLVideoElement||d instanceof HTMLAudioElement?e.appendChild(d.cloneNode(!0)):e.appendChild(d)})}},j=(e,t)=>{if(!t)return!1;let n=t.split(/\s+/);for(let o=0;o{Array.from(e.classList).forEach(n=>{!Object.values(i).includes(n)&&!Object.values(De).includes(n)&&!Object.values(t.showClass||{}).includes(n)&&e.classList.remove(n)})},O=(e,t,n)=>{if(oo(e,t),!t.customClass)return;let o=t.customClass[n];if(o){if(typeof o!="string"&&!o.forEach){B(`Invalid type of customClass.${n}! Expected string or iterable object, got "${typeof o}"`);return}h(e,o)}},je=(e,t)=>{if(!t)return null;switch(t){case"select":case"textarea":case"file":return e.querySelector(`.${i.popup} > .${i[t]}`);case"checkbox":return e.querySelector(`.${i.popup} > .${i.checkbox} input`);case"radio":return e.querySelector(`.${i.popup} > .${i.radio} input:checked`)||e.querySelector(`.${i.popup} > .${i.radio} input:first-child`);case"range":return e.querySelector(`.${i.popup} > .${i.range} input`);default:return e.querySelector(`.${i.popup} > .${i.input}`)}},Wt=e=>{if(e.focus(),e.type!=="file"){let t=e.value;e.value="",e.value=t}},Yt=(e,t,n)=>{!e||!t||(typeof t=="string"&&(t=t.split(/\s+/).filter(Boolean)),t.forEach(o=>{Array.isArray(e)?e.forEach(s=>{n?s.classList.add(o):s.classList.remove(o)}):n?e.classList.add(o):e.classList.remove(o)}))},h=(e,t)=>{Yt(e,t,!0)},N=(e,t)=>{Yt(e,t,!1)},U=(e,t)=>{let n=Array.from(e.children);for(let o=0;o{n===`${parseInt(n)}`&&(n=parseInt(n)),n||parseInt(n)===0?e.style.setProperty(t,typeof n=="number"?`${n}px`:n):e.style.removeProperty(t)},A=function(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"flex";e&&(e.style.display=t)},D=e=>{e&&(e.style.display="none")},ut=function(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"block";e&&new MutationObserver(()=>{ke(e,e.innerHTML,t)}).observe(e,{childList:!0,subtree:!0})},At=(e,t,n,o)=>{let s=e.querySelector(t);s&&s.style.setProperty(n,o)},ke=function(e,t){let n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:"flex";t?A(e,n):D(e)},M=e=>!!(e&&(e.offsetWidth||e.offsetHeight||e.getClientRects().length)),ro=()=>!M(z())&&!M(ne())&&!M(le()),It=e=>e.scrollHeight>e.clientHeight,Vt=e=>{let t=window.getComputedStyle(e),n=parseFloat(t.getPropertyValue("animation-duration")||"0"),o=parseFloat(t.getPropertyValue("transition-duration")||"0");return n>0||o>0},dt=function(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,n=qe();n&&M(n)&&(t&&(n.style.transition="none",n.style.width="100%"),setTimeout(()=>{n.style.transition=`width ${e/1e3}s linear`,n.style.width="0%"},10))},so=()=>{let e=qe();if(!e)return;let t=parseInt(window.getComputedStyle(e).width);e.style.removeProperty("transition"),e.style.width="100%";let n=parseInt(window.getComputedStyle(e).width),o=t/n*100;e.style.width=`${o}%`},ao=()=>typeof window>"u"||typeof document>"u",io=` +
    + +
      +
      + +

      +
      + + +
      - -
      -
      -`.replace(/(^|\n)\s*/g,""),lo=()=>{let e=L();return e?(e.remove(),N([document.documentElement,document.body],[i["no-backdrop"],i["toast-shown"],i["has-column"]]),!0):!1},Z=()=>{w.currentInstance.resetValidationMessage()},co=()=>{let e=y(),t=U(e,i.input),n=U(e,i.file),o=e.querySelector(`.${i.range} input`),s=e.querySelector(`.${i.range} output`),a=U(e,i.select),d=e.querySelector(`.${i.checkbox} input`),m=U(e,i.textarea);t.oninput=Z,n.onchange=Z,a.onchange=Z,d.onchange=Z,m.oninput=Z,o.oninput=()=>{Z(),s.value=o.value},o.onchange=()=>{Z(),s.value=o.value}},uo=e=>typeof e=="string"?document.querySelector(e):e,po=e=>{let t=y();t.setAttribute("role",e.toast?"alert":"dialog"),t.setAttribute("aria-live",e.toast?"polite":"assertive"),e.toast||t.setAttribute("aria-modal","true")},mo=e=>{window.getComputedStyle(e).direction==="rtl"&&h(L(),i.rtl)},fo=e=>{let t=lo();if(ao()){te("SweetAlert2 requires document to initialize");return}let n=document.createElement("div");n.className=i.container,t&&h(n,i["no-transition"]),_(n,io),n.dataset.swal2Theme=e.theme;let o=uo(e.target);o.appendChild(n),po(e),mo(o),co()},pt=(e,t)=>{e instanceof HTMLElement?t.appendChild(e):typeof e=="object"?wo(e,t):e&&_(t,e)},wo=(e,t)=>{e.jquery?go(t,e):_(t,e.toString())},go=(e,t)=>{if(e.textContent="",0 in t)for(let n=0;n in t;n++)e.appendChild(t[n].cloneNode(!0));else e.appendChild(t.cloneNode(!0))},ho=(e,t)=>{let n=ve(),o=ce();!n||!o||(!t.showConfirmButton&&!t.showDenyButton&&!t.showCancelButton?D(n):A(n),O(n,t,"actions"),yo(n,o,t),_(o,t.loaderHtml||""),O(o,t,"loader"))};function yo(e,t,n){let o=z(),s=ne(),a=le();!o||!s||!a||(Xe(o,"confirm",n),Xe(s,"deny",n),Xe(a,"cancel",n),bo(o,s,a,n),n.reverseButtons&&(n.toast?(e.insertBefore(a,o),e.insertBefore(s,o)):(e.insertBefore(a,t),e.insertBefore(s,t),e.insertBefore(o,t))))}function bo(e,t,n,o){if(!o.buttonsStyling){N([e,t,n],i.styled);return}h([e,t,n],i.styled),o.confirmButtonColor&&(e.style.backgroundColor=o.confirmButtonColor,h(e,i["default-outline"])),o.denyButtonColor&&(t.style.backgroundColor=o.denyButtonColor,h(t,i["default-outline"])),o.cancelButtonColor&&(n.style.backgroundColor=o.cancelButtonColor,h(n,i["default-outline"]))}function Xe(e,t,n){let o=nt(t);ke(e,n[`show${o}Button`],"inline-block"),_(e,n[`${t}ButtonText`]||""),e.setAttribute("aria-label",n[`${t}ButtonAriaLabel`]||""),e.className=i[t],O(e,n,`${t}Button`)}var vo=(e,t)=>{let n=it();n&&(_(n,t.closeButtonHtml||""),O(n,t,"closeButton"),ke(n,t.showCloseButton),n.setAttribute("aria-label",t.closeButtonAriaLabel||""))},ko=(e,t)=>{let n=L();n&&(Co(n,t.backdrop),xo(n,t.position),Eo(n,t.grow),O(n,t,"container"))};function Co(e,t){typeof t=="string"?e.style.background=t:t||h([document.documentElement,document.body],i["no-backdrop"])}function xo(e,t){t&&(t in i?h(e,i[t]):(B('The "position" parameter is not valid, defaulting to "center"'),h(e,i.center)))}function Eo(e,t){t&&h(e,i[`grow-${t}`])}var v={innerParams:new WeakMap,domCache:new WeakMap},So=["input","file","range","select","radio","checkbox","textarea"],Po=(e,t)=>{let n=y();if(!n)return;let o=v.innerParams.get(e),s=!o||t.input!==o.input;So.forEach(a=>{let d=U(n,i[a]);d&&(To(a,t.inputAttributes),d.className=i[a],s&&D(d))}),t.input&&(s&&Ao(t),Do(t))},Ao=e=>{if(!e.input)return;if(!S[e.input]){te(`Unexpected type of input! Expected ${Object.keys(S).join(" | ")}, got "${e.input}"`);return}let t=Ut(e.input);if(!t)return;let n=S[e.input](t,e);A(t),e.inputAutoFocus&&setTimeout(()=>{Wt(n)})},Io=e=>{for(let t=0;t{let n=y();if(!n)return;let o=je(n,e);if(o){Io(o);for(let s in t)o.setAttribute(s,t[s])}},Do=e=>{if(!e.input)return;let t=Ut(e.input);t&&O(t,e,"input")},mt=(e,t)=>{!e.placeholder&&t.inputPlaceholder&&(e.placeholder=t.inputPlaceholder)},Ce=(e,t,n)=>{if(n.inputLabel){let o=document.createElement("label"),s=i["input-label"];o.setAttribute("for",e.id),o.className=s,typeof n.customClass=="object"&&h(o,n.customClass.inputLabel),o.innerText=n.inputLabel,t.insertAdjacentElement("beforebegin",o)}},Ut=e=>{let t=y();if(t)return U(t,i[e]||i.input)},Be=(e,t)=>{["string","number"].includes(typeof t)?e.value=`${t}`:rt(t)||B(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof t}"`)},S={};S.text=S.email=S.password=S.number=S.tel=S.url=S.search=S.date=S["datetime-local"]=S.time=S.week=S.month=(e,t)=>(Be(e,t.inputValue),Ce(e,e,t),mt(e,t),e.type=t.input,e);S.file=(e,t)=>(Ce(e,e,t),mt(e,t),e);S.range=(e,t)=>{let n=e.querySelector("input"),o=e.querySelector("output");return Be(n,t.inputValue),n.type=t.input,Be(o,t.inputValue),Ce(n,e,t),e};S.select=(e,t)=>{if(e.textContent="",t.inputPlaceholder){let n=document.createElement("option");_(n,t.inputPlaceholder),n.value="",n.disabled=!0,n.selected=!0,e.appendChild(n)}return Ce(e,e,t),e};S.radio=e=>(e.textContent="",e);S.checkbox=(e,t)=>{let n=je(y(),"checkbox");n.value="1",n.checked=!!t.inputValue;let o=e.querySelector("span");return _(o,t.inputPlaceholder||t.inputLabel),n};S.textarea=(e,t)=>{Be(e,t.inputValue),mt(e,t),Ce(e,e,t);let n=o=>parseInt(window.getComputedStyle(o).marginLeft)+parseInt(window.getComputedStyle(o).marginRight);return setTimeout(()=>{if("MutationObserver"in window){let o=parseInt(window.getComputedStyle(y()).width),s=()=>{if(!document.body.contains(e))return;let a=e.offsetWidth+n(e);a>o?y().style.width=`${a}px`:J(y(),"width",t.width)};new MutationObserver(s).observe(e,{attributes:!0,attributeFilter:["style"]})}}),e};var Bo=(e,t)=>{let n=st();n&&(ut(n),O(n,t,"htmlContainer"),t.html?(pt(t.html,n),A(n,"block")):t.text?(n.textContent=t.text,A(n,"block")):D(n),Po(e,t))},Lo=(e,t)=>{let n=jt();n&&(ut(n),ke(n,t.footer,"block"),t.footer&&pt(t.footer,n),O(n,t,"footer"))},Mo=(e,t)=>{let n=v.innerParams.get(e),o=ie();if(!o)return;if(n&&t.icon===n.icon){Dt(o,t),Tt(o,t);return}if(!t.icon&&!t.iconHtml){D(o);return}if(t.icon&&Object.keys(De).indexOf(t.icon)===-1){te(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${t.icon}"`),D(o);return}A(o),Dt(o,t),Tt(o,t),h(o,t.showClass&&t.showClass.icon),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",Gt)},Tt=(e,t)=>{for(let[n,o]of Object.entries(De))t.icon!==n&&N(e,o);h(e,t.icon&&De[t.icon]),Ho(e,t),Gt(),O(e,t,"icon")},Gt=()=>{let e=y();if(!e)return;let t=window.getComputedStyle(e).getPropertyValue("background-color"),n=e.querySelectorAll("[class^=swal2-success-circular-line], .swal2-success-fix");for(let o=0;o{let e=L();return e?(e.remove(),N([document.documentElement,document.body],[i["no-backdrop"],i["toast-shown"],i["has-column"]]),!0):!1},X=()=>{w.currentInstance.resetValidationMessage()},io=()=>{let e=y(),t=U(e,i.input),n=U(e,i.file),o=e.querySelector(`.${i.range} input`),s=e.querySelector(`.${i.range} output`),a=U(e,i.select),d=e.querySelector(`.${i.checkbox} input`),m=U(e,i.textarea);t.oninput=X,n.onchange=X,a.onchange=X,d.onchange=X,m.oninput=X,o.oninput=()=>{X(),s.value=o.value},o.onchange=()=>{X(),s.value=o.value}},lo=e=>typeof e=="string"?document.querySelector(e):e,co=e=>{let t=y();t.setAttribute("role",e.toast?"alert":"dialog"),t.setAttribute("aria-live",e.toast?"polite":"assertive"),e.toast||t.setAttribute("aria-modal","true")},uo=e=>{window.getComputedStyle(e).direction==="rtl"&&h(L(),i.rtl)},po=e=>{let t=ao();if(ro()){ee("SweetAlert2 requires document to initialize");return}let n=document.createElement("div");n.className=i.container,t&&h(n,i["no-transition"]),_(n,so),n.dataset.swal2Theme=e.theme;let o=lo(e.target);o.appendChild(n),co(e),uo(o),io()},pt=(e,t)=>{e instanceof HTMLElement?t.appendChild(e):typeof e=="object"?mo(e,t):e&&_(t,e)},mo=(e,t)=>{e.jquery?fo(t,e):_(t,e.toString())},fo=(e,t)=>{if(e.textContent="",0 in t)for(let n=0;n in t;n++)e.appendChild(t[n].cloneNode(!0));else e.appendChild(t.cloneNode(!0))},wo=(e,t)=>{let n=ve(),o=le();!n||!o||(!t.showConfirmButton&&!t.showDenyButton&&!t.showCancelButton?D(n):A(n),O(n,t,"actions"),go(n,o,t),_(o,t.loaderHtml||""),O(o,t,"loader"))};function go(e,t,n){let o=z(),s=te(),a=ie();!o||!s||!a||(Xe(o,"confirm",n),Xe(s,"deny",n),Xe(a,"cancel",n),ho(o,s,a,n),n.reverseButtons&&(n.toast?(e.insertBefore(a,o),e.insertBefore(s,o)):(e.insertBefore(a,t),e.insertBefore(s,t),e.insertBefore(o,t))))}function ho(e,t,n,o){if(!o.buttonsStyling){N([e,t,n],i.styled);return}h([e,t,n],i.styled),o.confirmButtonColor&&(e.style.backgroundColor=o.confirmButtonColor,h(e,i["default-outline"])),o.denyButtonColor&&(t.style.backgroundColor=o.denyButtonColor,h(t,i["default-outline"])),o.cancelButtonColor&&(n.style.backgroundColor=o.cancelButtonColor,h(n,i["default-outline"]))}function Xe(e,t,n){let o=nt(t);ke(e,n[`show${o}Button`],"inline-block"),_(e,n[`${t}ButtonText`]||""),e.setAttribute("aria-label",n[`${t}ButtonAriaLabel`]||""),e.className=i[t],O(e,n,`${t}Button`)}var yo=(e,t)=>{let n=it();n&&(_(n,t.closeButtonHtml||""),O(n,t,"closeButton"),ke(n,t.showCloseButton),n.setAttribute("aria-label",t.closeButtonAriaLabel||""))},bo=(e,t)=>{let n=L();n&&(vo(n,t.backdrop),ko(n,t.position),Co(n,t.grow),O(n,t,"container"))};function vo(e,t){typeof t=="string"?e.style.background=t:t||h([document.documentElement,document.body],i["no-backdrop"])}function ko(e,t){t&&(t in i?h(e,i[t]):(B('The "position" parameter is not valid, defaulting to "center"'),h(e,i.center)))}function Co(e,t){t&&h(e,i[`grow-${t}`])}var v={innerParams:new WeakMap,domCache:new WeakMap},xo=["input","file","range","select","radio","checkbox","textarea"],Eo=(e,t)=>{let n=y();if(!n)return;let o=v.innerParams.get(e),s=!o||t.input!==o.input;xo.forEach(a=>{let d=U(n,i[a]);d&&(Ao(a,t.inputAttributes),d.className=i[a],s&&D(d))}),t.input&&(s&&So(t),Io(t))},So=e=>{if(!e.input)return;if(!S[e.input]){ee(`Unexpected type of input! Expected ${Object.keys(S).join(" | ")}, got "${e.input}"`);return}let t=Vt(e.input);if(!t)return;let n=S[e.input](t,e);A(t),e.inputAutoFocus&&setTimeout(()=>{jt(n)})},Po=e=>{for(let t=0;t{let n=y();if(!n)return;let o=je(n,e);if(o){Po(o);for(let s in t)o.setAttribute(s,t[s])}},Io=e=>{if(!e.input)return;let t=Vt(e.input);t&&O(t,e,"input")},mt=(e,t)=>{!e.placeholder&&t.inputPlaceholder&&(e.placeholder=t.inputPlaceholder)},Ce=(e,t,n)=>{if(n.inputLabel){let o=document.createElement("label"),s=i["input-label"];o.setAttribute("for",e.id),o.className=s,typeof n.customClass=="object"&&h(o,n.customClass.inputLabel),o.innerText=n.inputLabel,t.insertAdjacentElement("beforebegin",o)}},Vt=e=>{let t=y();if(t)return U(t,i[e]||i.input)},Be=(e,t)=>{["string","number"].includes(typeof t)?e.value=`${t}`:rt(t)||B(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof t}"`)},S={};S.text=S.email=S.password=S.number=S.tel=S.url=S.search=S.date=S["datetime-local"]=S.time=S.week=S.month=(e,t)=>(Be(e,t.inputValue),Ce(e,e,t),mt(e,t),e.type=t.input,e);S.file=(e,t)=>(Ce(e,e,t),mt(e,t),e);S.range=(e,t)=>{let n=e.querySelector("input"),o=e.querySelector("output");return Be(n,t.inputValue),n.type=t.input,Be(o,t.inputValue),Ce(n,e,t),e};S.select=(e,t)=>{if(e.textContent="",t.inputPlaceholder){let n=document.createElement("option");_(n,t.inputPlaceholder),n.value="",n.disabled=!0,n.selected=!0,e.appendChild(n)}return Ce(e,e,t),e};S.radio=e=>(e.textContent="",e);S.checkbox=(e,t)=>{let n=je(y(),"checkbox");n.value="1",n.checked=!!t.inputValue;let o=e.querySelector("span");return _(o,t.inputPlaceholder||t.inputLabel),n};S.textarea=(e,t)=>{Be(e,t.inputValue),mt(e,t),Ce(e,e,t);let n=o=>parseInt(window.getComputedStyle(o).marginLeft)+parseInt(window.getComputedStyle(o).marginRight);return setTimeout(()=>{if("MutationObserver"in window){let o=parseInt(window.getComputedStyle(y()).width),s=()=>{if(!document.body.contains(e))return;let a=e.offsetWidth+n(e);a>o?y().style.width=`${a}px`:Z(y(),"width",t.width)};new MutationObserver(s).observe(e,{attributes:!0,attributeFilter:["style"]})}}),e};var To=(e,t)=>{let n=st();n&&(ut(n),O(n,t,"htmlContainer"),t.html?(pt(t.html,n),A(n,"block")):t.text?(n.textContent=t.text,A(n,"block")):D(n),Eo(e,t))},Do=(e,t)=>{let n=Ft();n&&(ut(n),ke(n,t.footer,"block"),t.footer&&pt(t.footer,n),O(n,t,"footer"))},Bo=(e,t)=>{let n=v.innerParams.get(e),o=ae();if(!o)return;if(n&&t.icon===n.icon){Tt(o,t),It(o,t);return}if(!t.icon&&!t.iconHtml){D(o);return}if(t.icon&&Object.keys(De).indexOf(t.icon)===-1){ee(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${t.icon}"`),D(o);return}A(o),Tt(o,t),It(o,t),h(o,t.showClass&&t.showClass.icon),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",Ut)},It=(e,t)=>{for(let[n,o]of Object.entries(De))t.icon!==n&&N(e,o);h(e,t.icon&&De[t.icon]),$o(e,t),Ut(),O(e,t,"icon")},Ut=()=>{let e=y();if(!e)return;let t=window.getComputedStyle(e).getPropertyValue("background-color"),n=e.querySelectorAll("[class^=swal2-success-circular-line], .swal2-success-fix");for(let o=0;o
      -`,Oo=` +`,Mo=` -`,Dt=(e,t)=>{if(!t.icon&&!t.iconHtml)return;let n=e.innerHTML,o="";t.iconHtml?o=Bt(t.iconHtml):t.icon==="success"?(o=$o,n=n.replace(/ style=".*?"/g,"")):t.icon==="error"?o=Oo:t.icon&&(o=Bt({question:"?",warning:"!",info:"i"}[t.icon])),n.trim()!==o.trim()&&_(e,o)},Ho=(e,t)=>{if(t.iconColor){e.style.color=t.iconColor,e.style.borderColor=t.iconColor;for(let n of[".swal2-success-line-tip",".swal2-success-line-long",".swal2-x-mark-line-left",".swal2-x-mark-line-right"])At(e,n,"background-color",t.iconColor);At(e,".swal2-success-ring","border-color",t.iconColor)}},Bt=e=>`
      ${e}
      `,_o=(e,t)=>{let n=Ft();if(n){if(!t.imageUrl){D(n);return}A(n,""),n.setAttribute("src",t.imageUrl),n.setAttribute("alt",t.imageAlt||""),J(n,"width",t.imageWidth),J(n,"height",t.imageHeight),n.className=i.image,O(n,t,"image")}},ft=!1,Kt=0,Xt=0,Zt=0,Jt=0,No=e=>{e.addEventListener("mousedown",Le),document.body.addEventListener("mousemove",Me),e.addEventListener("mouseup",$e),e.addEventListener("touchstart",Le),document.body.addEventListener("touchmove",Me),e.addEventListener("touchend",$e)},Ro=e=>{e.removeEventListener("mousedown",Le),document.body.removeEventListener("mousemove",Me),e.removeEventListener("mouseup",$e),e.removeEventListener("touchstart",Le),document.body.removeEventListener("touchmove",Me),e.removeEventListener("touchend",$e)},Le=e=>{let t=y();if(e.target===t||ie().contains(e.target)){ft=!0;let n=Qt(e);Kt=n.clientX,Xt=n.clientY,Zt=parseInt(t.style.insetInlineStart)||0,Jt=parseInt(t.style.insetBlockStart)||0,h(t,"swal2-dragging")}},Me=e=>{let t=y();if(ft){let{clientX:n,clientY:o}=Qt(e);t.style.insetInlineStart=`${Zt+(n-Kt)}px`,t.style.insetBlockStart=`${Jt+(o-Xt)}px`}},$e=()=>{let e=y();ft=!1,N(e,"swal2-dragging")},Qt=e=>{let t=0,n=0;return e.type.startsWith("mouse")?(t=e.clientX,n=e.clientY):e.type.startsWith("touch")&&(t=e.touches[0].clientX,n=e.touches[0].clientY),{clientX:t,clientY:n}},zo=(e,t)=>{let n=L(),o=y();if(!(!n||!o)){if(t.toast){J(n,"width",t.width),o.style.width="100%";let s=ce();s&&o.insertBefore(s,ie())}else J(o,"width",t.width);J(o,"padding",t.padding),t.color&&(o.style.color=t.color),t.background&&(o.style.background=t.background),D(ze()),qo(o,t),t.draggable&&!t.toast?(h(o,i.draggable),No(o)):(N(o,i.draggable),Ro(o))}},qo=(e,t)=>{let n=t.showClass||{};e.className=`${i.popup} ${M(e)?n.popup:""}`,t.toast?(h([document.documentElement,document.body],i["toast-shown"]),h(e,i.toast)):h(e,i.modal),O(e,t,"popup"),typeof t.customClass=="string"&&h(e,t.customClass),t.icon&&h(e,i[`icon-${t.icon}`])},Fo=(e,t)=>{let n=at();if(!n)return;let{progressSteps:o,currentProgressStep:s}=t;if(!o||o.length===0||s===void 0){D(n);return}A(n),n.textContent="",s>=o.length&&B("Invalid currentProgressStep parameter, it should be less than progressSteps.length (currentProgressStep like JS arrays starts from 0)"),o.forEach((a,d)=>{let m=jo(a);if(n.appendChild(m),d===s&&h(m,i["active-progress-step"]),d!==o.length-1){let f=Wo(t);n.appendChild(f)}})},jo=e=>{let t=document.createElement("li");return h(t,i["progress-step"]),_(t,e),t},Wo=e=>{let t=document.createElement("li");return h(t,i["progress-step-line"]),e.progressStepsDistance&&J(t,"width",e.progressStepsDistance),t},Yo=(e,t)=>{let n=qt();n&&(ut(n),ke(n,t.title||t.titleText,"block"),t.title&&pt(t.title,n),t.titleText&&(n.innerText=t.titleText),O(n,t,"title"))},en=(e,t)=>{zo(e,t),ko(e,t),Fo(e,t),Mo(e,t),_o(e,t),Yo(e,t),vo(e,t),Bo(e,t),ho(e,t),Lo(e,t);let n=y();typeof t.didRender=="function"&&n&&t.didRender(n),w.eventEmitter.emit("didRender",n)},Vo=()=>M(y()),tn=()=>{var e;return(e=z())===null||e===void 0?void 0:e.click()},Uo=()=>{var e;return(e=ne())===null||e===void 0?void 0:e.click()},Go=()=>{var e;return(e=le())===null||e===void 0?void 0:e.click()},ue=Object.freeze({cancel:"cancel",backdrop:"backdrop",close:"close",esc:"esc",timer:"timer"}),nn=e=>{e.keydownTarget&&e.keydownHandlerAdded&&(e.keydownTarget.removeEventListener("keydown",e.keydownHandler,{capture:e.keydownListenerCapture}),e.keydownHandlerAdded=!1)},Ko=(e,t,n)=>{nn(e),t.toast||(e.keydownHandler=o=>Zo(t,o,n),e.keydownTarget=t.keydownListenerCapture?window:y(),e.keydownListenerCapture=t.keydownListenerCapture,e.keydownTarget.addEventListener("keydown",e.keydownHandler,{capture:e.keydownListenerCapture}),e.keydownHandlerAdded=!0)},Je=(e,t)=>{var n;let o=lt();if(o.length){e=e+t,e===o.length?e=0:e===-1&&(e=o.length-1),o[e].focus();return}(n=y())===null||n===void 0||n.focus()},on=["ArrowRight","ArrowDown"],Xo=["ArrowLeft","ArrowUp"],Zo=(e,t,n)=>{e&&(t.isComposing||t.keyCode===229||(e.stopKeydownPropagation&&t.stopPropagation(),t.key==="Enter"?Jo(t,e):t.key==="Tab"?Qo(t):[...on,...Xo].includes(t.key)?er(t.key):t.key==="Escape"&&tr(t,e,n)))},Jo=(e,t)=>{if(!Re(t.allowEnterKey))return;let n=je(y(),t.input);if(e.target&&n&&e.target instanceof HTMLElement&&e.target.outerHTML===n.outerHTML){if(["textarea","file"].includes(t.input))return;tn(),e.preventDefault()}},Qo=e=>{let t=e.target,n=lt(),o=-1;for(let s=0;s{let t=ve(),n=z(),o=ne(),s=le();if(!t||!n||!o||!s)return;let a=[n,o,s];if(document.activeElement instanceof HTMLElement&&!a.includes(document.activeElement))return;let d=on.includes(e)?"nextElementSibling":"previousElementSibling",m=document.activeElement;if(m){for(let f=0;f{Re(t.allowEscapeKey)&&(e.preventDefault(),n(ue.esc))},se={swalPromiseResolve:new WeakMap,swalPromiseReject:new WeakMap},nr=()=>{let e=L();Array.from(document.body.children).forEach(n=>{n.contains(e)||(n.hasAttribute("aria-hidden")&&n.setAttribute("data-previous-aria-hidden",n.getAttribute("aria-hidden")||""),n.setAttribute("aria-hidden","true"))})},rn=()=>{Array.from(document.body.children).forEach(t=>{t.hasAttribute("data-previous-aria-hidden")?(t.setAttribute("aria-hidden",t.getAttribute("data-previous-aria-hidden")||""),t.removeAttribute("data-previous-aria-hidden")):t.removeAttribute("aria-hidden")})},sn=typeof window<"u"&&!!window.GestureEvent,or=()=>{if(sn&&!j(document.body,i.iosfix)){let e=document.body.scrollTop;document.body.style.top=`${e*-1}px`,h(document.body,i.iosfix),rr()}},rr=()=>{let e=L();if(!e)return;let t;e.ontouchstart=n=>{t=sr(n)},e.ontouchmove=n=>{t&&(n.preventDefault(),n.stopPropagation())}},sr=e=>{let t=e.target,n=L(),o=st();return!n||!o||ar(e)||ir(e)?!1:t===n||!It(n)&&t instanceof HTMLElement&&t.tagName!=="INPUT"&&t.tagName!=="TEXTAREA"&&!(It(o)&&o.contains(t))},ar=e=>e.touches&&e.touches.length&&e.touches[0].touchType==="stylus",ir=e=>e.touches&&e.touches.length>1,lr=()=>{if(j(document.body,i.iosfix)){let e=parseInt(document.body.style.top,10);N(document.body,i.iosfix),document.body.style.top="",document.body.scrollTop=e*-1}},cr=()=>{let e=document.createElement("div");e.className=i["scrollbar-measure"],document.body.appendChild(e);let t=e.getBoundingClientRect().width-e.clientWidth;return document.body.removeChild(e),t},oe=null,ur=e=>{oe===null&&(document.body.scrollHeight>window.innerHeight||e==="scroll")&&(oe=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right")),document.body.style.paddingRight=`${oe+cr()}px`)},dr=()=>{oe!==null&&(document.body.style.paddingRight=`${oe}px`,oe=null)};function an(e,t,n,o){Fe()?Lt(e,o):(Kn(n).then(()=>Lt(e,o)),nn(w)),sn?(t.setAttribute("style","display:none !important"),t.removeAttribute("class"),t.innerHTML=""):t.remove(),ct()&&(dr(),lr(),rn()),pr()}function pr(){N([document.documentElement,document.body],[i.shown,i["height-auto"],i["no-backdrop"],i["toast-shown"]])}function G(e){e=fr(e);let t=se.swalPromiseResolve.get(this),n=mr(this);this.isAwaitingPromise?e.isDismissed||(xe(this),t(e)):n&&t(e)}var mr=e=>{let t=y();if(!t)return!1;let n=v.innerParams.get(e);if(!n||j(t,n.hideClass.popup))return!1;N(t,n.showClass.popup),h(t,n.hideClass.popup);let o=L();return N(o,n.showClass.backdrop),h(o,n.hideClass.backdrop),wr(e,t,n),!0};function ln(e){let t=se.swalPromiseReject.get(this);xe(this),t&&t(e)}var xe=e=>{e.isAwaitingPromise&&(delete e.isAwaitingPromise,v.innerParams.get(e)||e._destroy())},fr=e=>typeof e>"u"?{isConfirmed:!1,isDenied:!1,isDismissed:!0}:Object.assign({isConfirmed:!1,isDenied:!1,isDismissed:!1},e),wr=(e,t,n)=>{var o;let s=L(),a=Vt(t);typeof n.willClose=="function"&&n.willClose(t),(o=w.eventEmitter)===null||o===void 0||o.emit("willClose",t),a?gr(e,t,s,n.returnFocus,n.didClose):an(e,s,n.returnFocus,n.didClose)},gr=(e,t,n,o,s)=>{w.swalCloseEventFinishedCallback=an.bind(null,e,n,o,s);let a=function(d){if(d.target===t){var m;(m=w.swalCloseEventFinishedCallback)===null||m===void 0||m.call(w),delete w.swalCloseEventFinishedCallback,t.removeEventListener("animationend",a),t.removeEventListener("transitionend",a)}};t.addEventListener("animationend",a),t.addEventListener("transitionend",a)},Lt=(e,t)=>{setTimeout(()=>{var n;typeof t=="function"&&t.bind(e.params)(),(n=w.eventEmitter)===null||n===void 0||n.emit("didClose"),e._destroy&&e._destroy()})},ae=e=>{let t=y();if(t||new ee,t=y(),!t)return;let n=ce();Fe()?D(ie()):hr(t,e),A(n),t.setAttribute("data-loading","true"),t.setAttribute("aria-busy","true"),t.focus()},hr=(e,t)=>{let n=ve(),o=ce();!n||!o||(!t&&M(z())&&(t=z()),A(n),t&&(D(t),o.setAttribute("data-button-to-replace",t.className),n.insertBefore(o,t)),h([e,n],i.loading))},yr=(e,t)=>{t.input==="select"||t.input==="radio"?xr(e,t):["text","email","number","tel","textarea"].some(n=>n===t.input)&&(ot(t.inputValue)||rt(t.inputValue))&&(ae(z()),Er(e,t))},br=(e,t)=>{let n=e.getInput();if(!n)return null;switch(t.input){case"checkbox":return vr(n);case"radio":return kr(n);case"file":return Cr(n);default:return t.inputAutoTrim?n.value.trim():n.value}},vr=e=>e.checked?1:0,kr=e=>e.checked?e.value:null,Cr=e=>e.files&&e.files.length?e.getAttribute("multiple")!==null?e.files:e.files[0]:null,xr=(e,t)=>{let n=y();if(!n)return;let o=s=>{t.input==="select"?Sr(n,Oe(s),t):t.input==="radio"&&Pr(n,Oe(s),t)};ot(t.inputOptions)||rt(t.inputOptions)?(ae(z()),ye(t.inputOptions).then(s=>{e.hideLoading(),o(s)})):typeof t.inputOptions=="object"?o(t.inputOptions):te(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof t.inputOptions}`)},Er=(e,t)=>{let n=e.getInput();n&&(D(n),ye(t.inputValue).then(o=>{n.value=t.input==="number"?`${parseFloat(o)||0}`:`${o}`,A(n),n.focus(),e.hideLoading()}).catch(o=>{te(`Error in inputValue promise: ${o}`),n.value="",A(n),n.focus(),e.hideLoading()}))};function Sr(e,t,n){let o=U(e,i.select);if(!o)return;let s=(a,d,m)=>{let f=document.createElement("option");f.value=m,_(f,d),f.selected=cn(m,n.inputValue),a.appendChild(f)};t.forEach(a=>{let d=a[0],m=a[1];if(Array.isArray(m)){let f=document.createElement("optgroup");f.label=d,f.disabled=!1,o.appendChild(f),m.forEach(I=>s(f,I[1],I[0]))}else s(o,m,d)}),o.focus()}function Pr(e,t,n){let o=U(e,i.radio);if(!o)return;t.forEach(a=>{let d=a[0],m=a[1],f=document.createElement("input"),I=document.createElement("label");f.type="radio",f.name=i.radio,f.value=d,cn(d,n.inputValue)&&(f.checked=!0);let X=document.createElement("span");_(X,m),X.className=i.label,I.appendChild(f),I.appendChild(X),o.appendChild(I)});let s=o.querySelectorAll("input");s.length&&s[0].focus()}var Oe=e=>{let t=[];return e instanceof Map?e.forEach((n,o)=>{let s=n;typeof s=="object"&&(s=Oe(s)),t.push([o,s])}):Object.keys(e).forEach(n=>{let o=e[n];typeof o=="object"&&(o=Oe(o)),t.push([n,o])}),t},cn=(e,t)=>!!t&&t.toString()===e.toString(),Ar=e=>{let t=v.innerParams.get(e);e.disableButtons(),t.input?un(e,"confirm"):gt(e,!0)},Ir=e=>{let t=v.innerParams.get(e);e.disableButtons(),t.returnInputValueOnDeny?un(e,"deny"):wt(e,!1)},Tr=(e,t)=>{e.disableButtons(),t(ue.cancel)},un=(e,t)=>{let n=v.innerParams.get(e);if(!n.input){te(`The "input" parameter is needed to be set when using returnInputValueOn${nt(t)}`);return}let o=e.getInput(),s=br(e,n);n.inputValidator?Dr(e,s,t):o&&!o.checkValidity()?(e.enableButtons(),e.showValidationMessage(n.validationMessage||o.validationMessage)):t==="deny"?wt(e,s):gt(e,s)},Dr=(e,t,n)=>{let o=v.innerParams.get(e);e.disableInput(),Promise.resolve().then(()=>ye(o.inputValidator(t,o.validationMessage))).then(a=>{e.enableButtons(),e.enableInput(),a?e.showValidationMessage(a):n==="deny"?wt(e,t):gt(e,t)})},wt=(e,t)=>{let n=v.innerParams.get(e||void 0);n.showLoaderOnDeny&&ae(ne()),n.preDeny?(e.isAwaitingPromise=!0,Promise.resolve().then(()=>ye(n.preDeny(t,n.validationMessage))).then(s=>{s===!1?(e.hideLoading(),xe(e)):e.close({isDenied:!0,value:typeof s>"u"?t:s})}).catch(s=>dn(e||void 0,s))):e.close({isDenied:!0,value:t})},Mt=(e,t)=>{e.close({isConfirmed:!0,value:t})},dn=(e,t)=>{e.rejectPromise(t)},gt=(e,t)=>{let n=v.innerParams.get(e||void 0);n.showLoaderOnConfirm&&ae(),n.preConfirm?(e.resetValidationMessage(),e.isAwaitingPromise=!0,Promise.resolve().then(()=>ye(n.preConfirm(t,n.validationMessage))).then(s=>{M(ze())||s===!1?(e.hideLoading(),xe(e)):Mt(e,typeof s>"u"?t:s)}).catch(s=>dn(e||void 0,s))):Mt(e,t)};function He(){let e=v.innerParams.get(this);if(!e)return;let t=v.domCache.get(this);D(t.loader),Fe()?e.icon&&A(ie()):Br(t),N([t.popup,t.actions],i.loading),t.popup.removeAttribute("aria-busy"),t.popup.removeAttribute("data-loading"),t.confirmButton.disabled=!1,t.denyButton.disabled=!1,t.cancelButton.disabled=!1}var Br=e=>{let t=e.popup.getElementsByClassName(e.loader.getAttribute("data-button-to-replace"));t.length?A(t[0],"inline-block"):ro()&&D(e.actions)};function pn(){let e=v.innerParams.get(this),t=v.domCache.get(this);return t?je(t.popup,e.input):null}function mn(e,t,n){let o=v.domCache.get(e);t.forEach(s=>{o[s].disabled=n})}function fn(e,t){let n=y();if(!(!n||!e))if(e.type==="radio"){let o=n.querySelectorAll(`[name="${i.radio}"]`);for(let s=0;sObject.prototype.hasOwnProperty.call(re,e),Cn=e=>Lr.indexOf(e)!==-1,xn=e=>Mr[e],Or=e=>{kn(e)||B(`Unknown parameter "${e}"`)},Hr=e=>{$r.includes(e)&&B(`The parameter "${e}" is incompatible with toasts`)},_r=e=>{let t=xn(e);t&&zt(e,t)},En=e=>{e.backdrop===!1&&e.allowOutsideClick&&B('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`'),e.theme&&!["light","dark","auto","borderless","embed-iframe"].includes(e.theme)&&B(`Invalid theme "${e.theme}". Expected "light", "dark", "auto", "borderless", or "embed-iframe"`);for(let t in e)Or(t),e.toast&&Hr(t),_r(t)};function Sn(e){let t=L(),n=y(),o=v.innerParams.get(this);if(!n||j(n,o.hideClass.popup)){B("You're trying to update the closed or closing popup, that won't work. Use the update() method in preConfirm parameter or show a new popup.");return}let s=Nr(e),a=Object.assign({},o,s);En(a),t.dataset.swal2Theme=a.theme,en(this,a),v.innerParams.set(this,a),Object.defineProperties(this,{params:{value:Object.assign({},this.params,e),writable:!1,enumerable:!0}})}var Nr=e=>{let t={};return Object.keys(e).forEach(n=>{Cn(n)?t[n]=e[n]:B(`Invalid parameter to update: ${n}`)}),t};function Pn(){let e=v.domCache.get(this),t=v.innerParams.get(this);if(!t){An(this);return}e.popup&&w.swalCloseEventFinishedCallback&&(w.swalCloseEventFinishedCallback(),delete w.swalCloseEventFinishedCallback),typeof t.didDestroy=="function"&&t.didDestroy(),w.eventEmitter.emit("didDestroy"),Rr(this)}var Rr=e=>{An(e),delete e.params,delete w.keydownHandler,delete w.keydownTarget,delete w.currentInstance},An=e=>{e.isAwaitingPromise?(Ze(v,e),e.isAwaitingPromise=!0):(Ze(se,e),Ze(v,e),delete e.isAwaitingPromise,delete e.disableButtons,delete e.enableButtons,delete e.getInput,delete e.disableInput,delete e.enableInput,delete e.hideLoading,delete e.disableLoading,delete e.showValidationMessage,delete e.resetValidationMessage,delete e.close,delete e.closePopup,delete e.closeModal,delete e.closeToast,delete e.rejectPromise,delete e.update,delete e._destroy)},Ze=(e,t)=>{for(let n in e)e[n].delete(t)},zr=Object.freeze({__proto__:null,_destroy:Pn,close:G,closeModal:G,closePopup:G,closeToast:G,disableButtons:gn,disableInput:yn,disableLoading:He,enableButtons:wn,enableInput:hn,getInput:pn,handleAwaitingPromise:xe,hideLoading:He,rejectPromise:ln,resetValidationMessage:vn,showValidationMessage:bn,update:Sn}),qr=(e,t,n)=>{e.toast?Fr(e,t,n):(Wr(t),Yr(t),Vr(e,t,n))},Fr=(e,t,n)=>{t.popup.onclick=()=>{e&&(jr(e)||e.timer||e.input)||n(ue.close)}},jr=e=>!!(e.showConfirmButton||e.showDenyButton||e.showCancelButton||e.showCloseButton),_e=!1,Wr=e=>{e.popup.onmousedown=()=>{e.container.onmouseup=function(t){e.container.onmouseup=()=>{},t.target===e.container&&(_e=!0)}}},Yr=e=>{e.container.onmousedown=t=>{t.target===e.container&&t.preventDefault(),e.popup.onmouseup=function(n){e.popup.onmouseup=()=>{},(n.target===e.popup||n.target instanceof HTMLElement&&e.popup.contains(n.target))&&(_e=!0)}}},Vr=(e,t,n)=>{t.container.onclick=o=>{if(_e){_e=!1;return}o.target===t.container&&Re(e.allowOutsideClick)&&n(ue.backdrop)}},Ur=e=>typeof e=="object"&&e.jquery,$t=e=>e instanceof Element||Ur(e),Gr=e=>{let t={};return typeof e[0]=="object"&&!$t(e[0])?Object.assign(t,e[0]):["title","html","icon"].forEach((n,o)=>{let s=e[o];typeof s=="string"||$t(s)?t[n]=s:s!==void 0&&te(`Unexpected type of ${n}! Expected "string" or "Element", got ${typeof s}`)}),t};function Kr(){for(var e=arguments.length,t=new Array(e),n=0;nw.timeout&&w.timeout.getTimerLeft(),In=()=>{if(w.timeout)return so(),w.timeout.stop()},Tn=()=>{if(w.timeout){let e=w.timeout.start();return dt(e),e}},Jr=()=>{let e=w.timeout;return e&&(e.running?In():Tn())},Qr=e=>{if(w.timeout){let t=w.timeout.increase(e);return dt(t,!0),t}},es=()=>!!(w.timeout&&w.timeout.isRunning()),Ot=!1,Qe={};function ts(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:"data-swal-template";Qe[e]=this,Ot||(document.body.addEventListener("click",ns),Ot=!0)}var ns=e=>{for(let t=e.target;t&&t!==document;t=t.parentNode)for(let n in Qe){let o=t.getAttribute(n);if(o){Qe[n].fire({template:o});return}}},et=class{constructor(){this.events={}}_getHandlersByEventName(t){return typeof this.events[t]>"u"&&(this.events[t]=[]),this.events[t]}on(t,n){let o=this._getHandlersByEventName(t);o.includes(n)||o.push(n)}once(t,n){var o=this;let s=function(){o.removeListener(t,s);for(var a=arguments.length,d=new Array(a),m=0;m1?n-1:0),s=1;s{try{a.apply(this,o)}catch(d){console.error(d)}})}removeListener(t,n){let o=this._getHandlersByEventName(t),s=o.indexOf(n);s>-1&&o.splice(s,1)}removeAllListeners(t){this.events[t]!==void 0&&(this.events[t].length=0)}reset(){this.events={}}};w.eventEmitter=new et;var os=(e,t)=>{w.eventEmitter.on(e,t)},rs=(e,t)=>{w.eventEmitter.once(e,t)},ss=(e,t)=>{if(!e){w.eventEmitter.reset();return}t?w.eventEmitter.removeListener(e,t):w.eventEmitter.removeAllListeners(e)},as=Object.freeze({__proto__:null,argsToParams:Gr,bindClickHandler:ts,clickCancel:Go,clickConfirm:tn,clickDeny:Uo,enableLoading:ae,fire:Kr,getActions:ve,getCancelButton:le,getCloseButton:it,getConfirmButton:z,getContainer:L,getDenyButton:ne,getFocusableElements:lt,getFooter:jt,getHtmlContainer:st,getIcon:ie,getIconContent:Qn,getImage:Ft,getInputLabel:eo,getLoader:ce,getPopup:y,getProgressSteps:at,getTimerLeft:Zr,getTimerProgressBar:qe,getTitle:qt,getValidationMessage:ze,increaseTimer:Qr,isDeprecatedParameter:xn,isLoading:no,isTimerRunning:es,isUpdatableParameter:Cn,isValidParameter:kn,isVisible:Vo,mixin:Xr,off:ss,on:os,once:rs,resumeTimer:Tn,showLoading:ae,stopTimer:In,toggleTimer:Jr}),tt=class{constructor(t,n){this.callback=t,this.remaining=n,this.running=!1,this.start()}start(){return this.running||(this.running=!0,this.started=new Date,this.id=setTimeout(this.callback,this.remaining)),this.remaining}stop(){return this.started&&this.running&&(this.running=!1,clearTimeout(this.id),this.remaining-=new Date().getTime()-this.started.getTime()),this.remaining}increase(t){let n=this.running;return n&&this.stop(),this.remaining+=t,n&&this.start(),this.remaining}getTimerLeft(){return this.running&&(this.stop(),this.start()),this.remaining}isRunning(){return this.running}},Dn=["swal-title","swal-html","swal-footer"],is=e=>{let t=typeof e.template=="string"?document.querySelector(e.template):e.template;if(!t)return{};let n=t.content;return ws(n),Object.assign(ls(n),cs(n),us(n),ds(n),ps(n),ms(n),fs(n,Dn))},ls=e=>{let t={};return Array.from(e.querySelectorAll("swal-param")).forEach(o=>{Q(o,["name","value"]);let s=o.getAttribute("name"),a=o.getAttribute("value");!s||!a||(typeof re[s]=="boolean"?t[s]=a!=="false":typeof re[s]=="object"?t[s]=JSON.parse(a):t[s]=a)}),t},cs=e=>{let t={};return Array.from(e.querySelectorAll("swal-function-param")).forEach(o=>{let s=o.getAttribute("name"),a=o.getAttribute("value");!s||!a||(t[s]=new Function(`return ${a}`)())}),t},us=e=>{let t={};return Array.from(e.querySelectorAll("swal-button")).forEach(o=>{Q(o,["type","color","aria-label"]);let s=o.getAttribute("type");!s||!["confirm","cancel","deny"].includes(s)||(t[`${s}ButtonText`]=o.innerHTML,t[`show${nt(s)}Button`]=!0,o.hasAttribute("color")&&(t[`${s}ButtonColor`]=o.getAttribute("color")),o.hasAttribute("aria-label")&&(t[`${s}ButtonAriaLabel`]=o.getAttribute("aria-label")))}),t},ds=e=>{let t={},n=e.querySelector("swal-image");return n&&(Q(n,["src","width","height","alt"]),n.hasAttribute("src")&&(t.imageUrl=n.getAttribute("src")||void 0),n.hasAttribute("width")&&(t.imageWidth=n.getAttribute("width")||void 0),n.hasAttribute("height")&&(t.imageHeight=n.getAttribute("height")||void 0),n.hasAttribute("alt")&&(t.imageAlt=n.getAttribute("alt")||void 0)),t},ps=e=>{let t={},n=e.querySelector("swal-icon");return n&&(Q(n,["type","color"]),n.hasAttribute("type")&&(t.icon=n.getAttribute("type")),n.hasAttribute("color")&&(t.iconColor=n.getAttribute("color")),t.iconHtml=n.innerHTML),t},ms=e=>{let t={},n=e.querySelector("swal-input");n&&(Q(n,["type","label","placeholder","value"]),t.input=n.getAttribute("type")||"text",n.hasAttribute("label")&&(t.inputLabel=n.getAttribute("label")),n.hasAttribute("placeholder")&&(t.inputPlaceholder=n.getAttribute("placeholder")),n.hasAttribute("value")&&(t.inputValue=n.getAttribute("value")));let o=Array.from(e.querySelectorAll("swal-input-option"));return o.length&&(t.inputOptions={},o.forEach(s=>{Q(s,["value"]);let a=s.getAttribute("value");if(!a)return;let d=s.innerHTML;t.inputOptions[a]=d})),t},fs=(e,t)=>{let n={};for(let o in t){let s=t[o],a=e.querySelector(s);a&&(Q(a,[]),n[s.replace(/^swal-/,"")]=a.innerHTML.trim())}return n},ws=e=>{let t=Dn.concat(["swal-param","swal-function-param","swal-button","swal-image","swal-icon","swal-input","swal-input-option"]);Array.from(e.children).forEach(n=>{let o=n.tagName.toLowerCase();t.includes(o)||B(`Unrecognized element <${o}>`)})},Q=(e,t)=>{Array.from(e.attributes).forEach(n=>{t.indexOf(n.name)===-1&&B([`Unrecognized attribute "${n.name}" on <${e.tagName.toLowerCase()}>.`,`${t.length?`Allowed attributes are: ${t.join(", ")}`:"To set the value, use HTML within the element."}`])})},Bn=10,gs=e=>{let t=L(),n=y();typeof e.willOpen=="function"&&e.willOpen(n),w.eventEmitter.emit("willOpen",n);let s=window.getComputedStyle(document.body).overflowY;bs(t,n,e),setTimeout(()=>{hs(t,n)},Bn),ct()&&(ys(t,e.scrollbarPadding,s),nr()),!Fe()&&!w.previousActiveElement&&(w.previousActiveElement=document.activeElement),typeof e.didOpen=="function"&&setTimeout(()=>e.didOpen(n)),w.eventEmitter.emit("didOpen",n),N(t,i["no-transition"])},Ne=e=>{let t=y();if(e.target!==t)return;let n=L();t.removeEventListener("animationend",Ne),t.removeEventListener("transitionend",Ne),n.style.overflowY="auto"},hs=(e,t)=>{Vt(t)?(e.style.overflowY="hidden",t.addEventListener("animationend",Ne),t.addEventListener("transitionend",Ne)):e.style.overflowY="auto"},ys=(e,t,n)=>{or(),t&&n!=="hidden"&&ur(n),setTimeout(()=>{e.scrollTop=0})},bs=(e,t,n)=>{h(e,n.showClass.backdrop),n.animation?(t.style.setProperty("opacity","0","important"),A(t,"grid"),setTimeout(()=>{h(t,n.showClass.popup),t.style.removeProperty("opacity")},Bn)):A(t,"grid"),h([document.documentElement,document.body],i.shown),n.heightAuto&&n.backdrop&&!n.toast&&h([document.documentElement,document.body],i["height-auto"])},Ht={email:(e,t)=>/^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(e)?Promise.resolve():Promise.resolve(t||"Invalid email address"),url:(e,t)=>/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-z]{2,63}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/.test(e)?Promise.resolve():Promise.resolve(t||"Invalid URL")};function vs(e){e.inputValidator||(e.input==="email"&&(e.inputValidator=Ht.email),e.input==="url"&&(e.inputValidator=Ht.url))}function ks(e){(!e.target||typeof e.target=="string"&&!document.querySelector(e.target)||typeof e.target!="string"&&!e.target.appendChild)&&(B('Target parameter is not valid, defaulting to "body"'),e.target="body")}function Cs(e){vs(e),e.showLoaderOnConfirm&&!e.preConfirm&&B(`showLoaderOnConfirm is set to true, but preConfirm is not defined. +`,Tt=(e,t)=>{if(!t.icon&&!t.iconHtml)return;let n=e.innerHTML,o="";t.iconHtml?o=Dt(t.iconHtml):t.icon==="success"?(o=Lo,n=n.replace(/ style=".*?"/g,"")):t.icon==="error"?o=Mo:t.icon&&(o=Dt({question:"?",warning:"!",info:"i"}[t.icon])),n.trim()!==o.trim()&&_(e,o)},$o=(e,t)=>{if(t.iconColor){e.style.color=t.iconColor,e.style.borderColor=t.iconColor;for(let n of[".swal2-success-line-tip",".swal2-success-line-long",".swal2-x-mark-line-left",".swal2-x-mark-line-right"])Pt(e,n,"background-color",t.iconColor);Pt(e,".swal2-success-ring","border-color",t.iconColor)}},Dt=e=>`
      ${e}
      `,Oo=(e,t)=>{let n=qt();if(n){if(!t.imageUrl){D(n);return}A(n,""),n.setAttribute("src",t.imageUrl),n.setAttribute("alt",t.imageAlt||""),Z(n,"width",t.imageWidth),Z(n,"height",t.imageHeight),n.className=i.image,O(n,t,"image")}},ft=!1,Gt=0,Kt=0,Xt=0,Zt=0,Ho=e=>{e.addEventListener("mousedown",Le),document.body.addEventListener("mousemove",Me),e.addEventListener("mouseup",$e),e.addEventListener("touchstart",Le),document.body.addEventListener("touchmove",Me),e.addEventListener("touchend",$e)},_o=e=>{e.removeEventListener("mousedown",Le),document.body.removeEventListener("mousemove",Me),e.removeEventListener("mouseup",$e),e.removeEventListener("touchstart",Le),document.body.removeEventListener("touchmove",Me),e.removeEventListener("touchend",$e)},Le=e=>{let t=y();if(e.target===t||ae().contains(e.target)){ft=!0;let n=Jt(e);Gt=n.clientX,Kt=n.clientY,Xt=parseInt(t.style.insetInlineStart)||0,Zt=parseInt(t.style.insetBlockStart)||0,h(t,"swal2-dragging")}},Me=e=>{let t=y();if(ft){let{clientX:n,clientY:o}=Jt(e);t.style.insetInlineStart=`${Xt+(n-Gt)}px`,t.style.insetBlockStart=`${Zt+(o-Kt)}px`}},$e=()=>{let e=y();ft=!1,N(e,"swal2-dragging")},Jt=e=>{let t=0,n=0;return e.type.startsWith("mouse")?(t=e.clientX,n=e.clientY):e.type.startsWith("touch")&&(t=e.touches[0].clientX,n=e.touches[0].clientY),{clientX:t,clientY:n}},No=(e,t)=>{let n=L(),o=y();if(!(!n||!o)){if(t.toast){Z(n,"width",t.width),o.style.width="100%";let s=le();s&&o.insertBefore(s,ae())}else Z(o,"width",t.width);Z(o,"padding",t.padding),t.color&&(o.style.color=t.color),t.background&&(o.style.background=t.background),D(ze()),Ro(o,t),t.draggable&&!t.toast?(h(o,i.draggable),Ho(o)):(N(o,i.draggable),_o(o))}},Ro=(e,t)=>{let n=t.showClass||{};e.className=`${i.popup} ${M(e)?n.popup:""}`,t.toast?(h([document.documentElement,document.body],i["toast-shown"]),h(e,i.toast)):h(e,i.modal),O(e,t,"popup"),typeof t.customClass=="string"&&h(e,t.customClass),t.icon&&h(e,i[`icon-${t.icon}`])},zo=(e,t)=>{let n=at();if(!n)return;let{progressSteps:o,currentProgressStep:s}=t;if(!o||o.length===0||s===void 0){D(n);return}A(n),n.textContent="",s>=o.length&&B("Invalid currentProgressStep parameter, it should be less than progressSteps.length (currentProgressStep like JS arrays starts from 0)"),o.forEach((a,d)=>{let m=qo(a);if(n.appendChild(m),d===s&&h(m,i["active-progress-step"]),d!==o.length-1){let f=Fo(t);n.appendChild(f)}})},qo=e=>{let t=document.createElement("li");return h(t,i["progress-step"]),_(t,e),t},Fo=e=>{let t=document.createElement("li");return h(t,i["progress-step-line"]),e.progressStepsDistance&&Z(t,"width",e.progressStepsDistance),t},jo=(e,t)=>{let n=zt();n&&(ut(n),ke(n,t.title||t.titleText,"block"),t.title&&pt(t.title,n),t.titleText&&(n.innerText=t.titleText),O(n,t,"title"))},Qt=(e,t)=>{No(e,t),bo(e,t),zo(e,t),Bo(e,t),Oo(e,t),jo(e,t),yo(e,t),To(e,t),wo(e,t),Do(e,t);let n=y();typeof t.didRender=="function"&&n&&t.didRender(n),w.eventEmitter.emit("didRender",n)},Wo=()=>M(y()),en=()=>{var e;return(e=z())===null||e===void 0?void 0:e.click()},Yo=()=>{var e;return(e=te())===null||e===void 0?void 0:e.click()},Vo=()=>{var e;return(e=ie())===null||e===void 0?void 0:e.click()},ce=Object.freeze({cancel:"cancel",backdrop:"backdrop",close:"close",esc:"esc",timer:"timer"}),tn=e=>{e.keydownTarget&&e.keydownHandlerAdded&&(e.keydownTarget.removeEventListener("keydown",e.keydownHandler,{capture:e.keydownListenerCapture}),e.keydownHandlerAdded=!1)},Uo=(e,t,n)=>{tn(e),t.toast||(e.keydownHandler=o=>Ko(t,o,n),e.keydownTarget=t.keydownListenerCapture?window:y(),e.keydownListenerCapture=t.keydownListenerCapture,e.keydownTarget.addEventListener("keydown",e.keydownHandler,{capture:e.keydownListenerCapture}),e.keydownHandlerAdded=!0)},Je=(e,t)=>{var n;let o=lt();if(o.length){e=e+t,e===o.length?e=0:e===-1&&(e=o.length-1),o[e].focus();return}(n=y())===null||n===void 0||n.focus()},nn=["ArrowRight","ArrowDown"],Go=["ArrowLeft","ArrowUp"],Ko=(e,t,n)=>{e&&(t.isComposing||t.keyCode===229||(e.stopKeydownPropagation&&t.stopPropagation(),t.key==="Enter"?Xo(t,e):t.key==="Tab"?Zo(t):[...nn,...Go].includes(t.key)?Jo(t.key):t.key==="Escape"&&Qo(t,e,n)))},Xo=(e,t)=>{if(!Re(t.allowEnterKey))return;let n=je(y(),t.input);if(e.target&&n&&e.target instanceof HTMLElement&&e.target.outerHTML===n.outerHTML){if(["textarea","file"].includes(t.input))return;en(),e.preventDefault()}},Zo=e=>{let t=e.target,n=lt(),o=-1;for(let s=0;s{let t=ve(),n=z(),o=te(),s=ie();if(!t||!n||!o||!s)return;let a=[n,o,s];if(document.activeElement instanceof HTMLElement&&!a.includes(document.activeElement))return;let d=nn.includes(e)?"nextElementSibling":"previousElementSibling",m=document.activeElement;if(m){for(let f=0;f{Re(t.allowEscapeKey)&&(e.preventDefault(),n(ce.esc))},re={swalPromiseResolve:new WeakMap,swalPromiseReject:new WeakMap},er=()=>{let e=L();Array.from(document.body.children).forEach(n=>{n.contains(e)||(n.hasAttribute("aria-hidden")&&n.setAttribute("data-previous-aria-hidden",n.getAttribute("aria-hidden")||""),n.setAttribute("aria-hidden","true"))})},on=()=>{Array.from(document.body.children).forEach(t=>{t.hasAttribute("data-previous-aria-hidden")?(t.setAttribute("aria-hidden",t.getAttribute("data-previous-aria-hidden")||""),t.removeAttribute("data-previous-aria-hidden")):t.removeAttribute("aria-hidden")})},rn=typeof window<"u"&&!!window.GestureEvent,tr=()=>{if(rn&&!j(document.body,i.iosfix)){let e=document.body.scrollTop;document.body.style.top=`${e*-1}px`,h(document.body,i.iosfix),nr()}},nr=()=>{let e=L();if(!e)return;let t;e.ontouchstart=n=>{t=or(n)},e.ontouchmove=n=>{t&&(n.preventDefault(),n.stopPropagation())}},or=e=>{let t=e.target,n=L(),o=st();return!n||!o||rr(e)||sr(e)?!1:t===n||!At(n)&&t instanceof HTMLElement&&t.tagName!=="INPUT"&&t.tagName!=="TEXTAREA"&&!(At(o)&&o.contains(t))},rr=e=>e.touches&&e.touches.length&&e.touches[0].touchType==="stylus",sr=e=>e.touches&&e.touches.length>1,ar=()=>{if(j(document.body,i.iosfix)){let e=parseInt(document.body.style.top,10);N(document.body,i.iosfix),document.body.style.top="",document.body.scrollTop=e*-1}},ir=()=>{let e=document.createElement("div");e.className=i["scrollbar-measure"],document.body.appendChild(e);let t=e.getBoundingClientRect().width-e.clientWidth;return document.body.removeChild(e),t},ne=null,lr=e=>{ne===null&&(document.body.scrollHeight>window.innerHeight||e==="scroll")&&(ne=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right")),document.body.style.paddingRight=`${ne+ir()}px`)},cr=()=>{ne!==null&&(document.body.style.paddingRight=`${ne}px`,ne=null)};function sn(e,t,n,o){Fe()?Bt(e,o):(Un(n).then(()=>Bt(e,o)),tn(w)),rn?(t.setAttribute("style","display:none !important"),t.removeAttribute("class"),t.innerHTML=""):t.remove(),ct()&&(cr(),ar(),on()),ur()}function ur(){N([document.documentElement,document.body],[i.shown,i["height-auto"],i["no-backdrop"],i["toast-shown"]])}function G(e){e=pr(e);let t=re.swalPromiseResolve.get(this),n=dr(this);this.isAwaitingPromise?e.isDismissed||(xe(this),t(e)):n&&t(e)}var dr=e=>{let t=y();if(!t)return!1;let n=v.innerParams.get(e);if(!n||j(t,n.hideClass.popup))return!1;N(t,n.showClass.popup),h(t,n.hideClass.popup);let o=L();return N(o,n.showClass.backdrop),h(o,n.hideClass.backdrop),mr(e,t,n),!0};function an(e){let t=re.swalPromiseReject.get(this);xe(this),t&&t(e)}var xe=e=>{e.isAwaitingPromise&&(delete e.isAwaitingPromise,v.innerParams.get(e)||e._destroy())},pr=e=>typeof e>"u"?{isConfirmed:!1,isDenied:!1,isDismissed:!0}:Object.assign({isConfirmed:!1,isDenied:!1,isDismissed:!1},e),mr=(e,t,n)=>{var o;let s=L(),a=Yt(t);typeof n.willClose=="function"&&n.willClose(t),(o=w.eventEmitter)===null||o===void 0||o.emit("willClose",t),a?fr(e,t,s,n.returnFocus,n.didClose):sn(e,s,n.returnFocus,n.didClose)},fr=(e,t,n,o,s)=>{w.swalCloseEventFinishedCallback=sn.bind(null,e,n,o,s);let a=function(d){if(d.target===t){var m;(m=w.swalCloseEventFinishedCallback)===null||m===void 0||m.call(w),delete w.swalCloseEventFinishedCallback,t.removeEventListener("animationend",a),t.removeEventListener("transitionend",a)}};t.addEventListener("animationend",a),t.addEventListener("transitionend",a)},Bt=(e,t)=>{setTimeout(()=>{var n;typeof t=="function"&&t.bind(e.params)(),(n=w.eventEmitter)===null||n===void 0||n.emit("didClose"),e._destroy&&e._destroy()})},se=e=>{let t=y();if(t||new Q,t=y(),!t)return;let n=le();Fe()?D(ae()):wr(t,e),A(n),t.setAttribute("data-loading","true"),t.setAttribute("aria-busy","true"),t.focus()},wr=(e,t)=>{let n=ve(),o=le();!n||!o||(!t&&M(z())&&(t=z()),A(n),t&&(D(t),o.setAttribute("data-button-to-replace",t.className),n.insertBefore(o,t)),h([e,n],i.loading))},gr=(e,t)=>{t.input==="select"||t.input==="radio"?kr(e,t):["text","email","number","tel","textarea"].some(n=>n===t.input)&&(ot(t.inputValue)||rt(t.inputValue))&&(se(z()),Cr(e,t))},hr=(e,t)=>{let n=e.getInput();if(!n)return null;switch(t.input){case"checkbox":return yr(n);case"radio":return br(n);case"file":return vr(n);default:return t.inputAutoTrim?n.value.trim():n.value}},yr=e=>e.checked?1:0,br=e=>e.checked?e.value:null,vr=e=>e.files&&e.files.length?e.getAttribute("multiple")!==null?e.files:e.files[0]:null,kr=(e,t)=>{let n=y();if(!n)return;let o=s=>{t.input==="select"?xr(n,Oe(s),t):t.input==="radio"&&Er(n,Oe(s),t)};ot(t.inputOptions)||rt(t.inputOptions)?(se(z()),ye(t.inputOptions).then(s=>{e.hideLoading(),o(s)})):typeof t.inputOptions=="object"?o(t.inputOptions):ee(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof t.inputOptions}`)},Cr=(e,t)=>{let n=e.getInput();n&&(D(n),ye(t.inputValue).then(o=>{n.value=t.input==="number"?`${parseFloat(o)||0}`:`${o}`,A(n),n.focus(),e.hideLoading()}).catch(o=>{ee(`Error in inputValue promise: ${o}`),n.value="",A(n),n.focus(),e.hideLoading()}))};function xr(e,t,n){let o=U(e,i.select);if(!o)return;let s=(a,d,m)=>{let f=document.createElement("option");f.value=m,_(f,d),f.selected=ln(m,n.inputValue),a.appendChild(f)};t.forEach(a=>{let d=a[0],m=a[1];if(Array.isArray(m)){let f=document.createElement("optgroup");f.label=d,f.disabled=!1,o.appendChild(f),m.forEach(I=>s(f,I[1],I[0]))}else s(o,m,d)}),o.focus()}function Er(e,t,n){let o=U(e,i.radio);if(!o)return;t.forEach(a=>{let d=a[0],m=a[1],f=document.createElement("input"),I=document.createElement("label");f.type="radio",f.name=i.radio,f.value=d,ln(d,n.inputValue)&&(f.checked=!0);let ge=document.createElement("span");_(ge,m),ge.className=i.label,I.appendChild(f),I.appendChild(ge),o.appendChild(I)});let s=o.querySelectorAll("input");s.length&&s[0].focus()}var Oe=e=>{let t=[];return e instanceof Map?e.forEach((n,o)=>{let s=n;typeof s=="object"&&(s=Oe(s)),t.push([o,s])}):Object.keys(e).forEach(n=>{let o=e[n];typeof o=="object"&&(o=Oe(o)),t.push([n,o])}),t},ln=(e,t)=>!!t&&t.toString()===e.toString(),Sr=e=>{let t=v.innerParams.get(e);e.disableButtons(),t.input?cn(e,"confirm"):gt(e,!0)},Pr=e=>{let t=v.innerParams.get(e);e.disableButtons(),t.returnInputValueOnDeny?cn(e,"deny"):wt(e,!1)},Ar=(e,t)=>{e.disableButtons(),t(ce.cancel)},cn=(e,t)=>{let n=v.innerParams.get(e);if(!n.input){ee(`The "input" parameter is needed to be set when using returnInputValueOn${nt(t)}`);return}let o=e.getInput(),s=hr(e,n);n.inputValidator?Ir(e,s,t):o&&!o.checkValidity()?(e.enableButtons(),e.showValidationMessage(n.validationMessage||o.validationMessage)):t==="deny"?wt(e,s):gt(e,s)},Ir=(e,t,n)=>{let o=v.innerParams.get(e);e.disableInput(),Promise.resolve().then(()=>ye(o.inputValidator(t,o.validationMessage))).then(a=>{e.enableButtons(),e.enableInput(),a?e.showValidationMessage(a):n==="deny"?wt(e,t):gt(e,t)})},wt=(e,t)=>{let n=v.innerParams.get(e||void 0);n.showLoaderOnDeny&&se(te()),n.preDeny?(e.isAwaitingPromise=!0,Promise.resolve().then(()=>ye(n.preDeny(t,n.validationMessage))).then(s=>{s===!1?(e.hideLoading(),xe(e)):e.close({isDenied:!0,value:typeof s>"u"?t:s})}).catch(s=>un(e||void 0,s))):e.close({isDenied:!0,value:t})},Lt=(e,t)=>{e.close({isConfirmed:!0,value:t})},un=(e,t)=>{e.rejectPromise(t)},gt=(e,t)=>{let n=v.innerParams.get(e||void 0);n.showLoaderOnConfirm&&se(),n.preConfirm?(e.resetValidationMessage(),e.isAwaitingPromise=!0,Promise.resolve().then(()=>ye(n.preConfirm(t,n.validationMessage))).then(s=>{M(ze())||s===!1?(e.hideLoading(),xe(e)):Lt(e,typeof s>"u"?t:s)}).catch(s=>un(e||void 0,s))):Lt(e,t)};function He(){let e=v.innerParams.get(this);if(!e)return;let t=v.domCache.get(this);D(t.loader),Fe()?e.icon&&A(ae()):Tr(t),N([t.popup,t.actions],i.loading),t.popup.removeAttribute("aria-busy"),t.popup.removeAttribute("data-loading"),t.confirmButton.disabled=!1,t.denyButton.disabled=!1,t.cancelButton.disabled=!1}var Tr=e=>{let t=e.popup.getElementsByClassName(e.loader.getAttribute("data-button-to-replace"));t.length?A(t[0],"inline-block"):no()&&D(e.actions)};function dn(){let e=v.innerParams.get(this),t=v.domCache.get(this);return t?je(t.popup,e.input):null}function pn(e,t,n){let o=v.domCache.get(e);t.forEach(s=>{o[s].disabled=n})}function mn(e,t){let n=y();if(!(!n||!e))if(e.type==="radio"){let o=n.querySelectorAll(`[name="${i.radio}"]`);for(let s=0;sObject.prototype.hasOwnProperty.call(oe,e),kn=e=>Dr.indexOf(e)!==-1,Cn=e=>Br[e],Mr=e=>{vn(e)||B(`Unknown parameter "${e}"`)},$r=e=>{Lr.includes(e)&&B(`The parameter "${e}" is incompatible with toasts`)},Or=e=>{let t=Cn(e);t&&Rt(e,t)},xn=e=>{e.backdrop===!1&&e.allowOutsideClick&&B('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`'),e.theme&&!["light","dark","auto","borderless","embed-iframe"].includes(e.theme)&&B(`Invalid theme "${e.theme}". Expected "light", "dark", "auto", "borderless", or "embed-iframe"`);for(let t in e)Mr(t),e.toast&&$r(t),Or(t)};function En(e){let t=L(),n=y(),o=v.innerParams.get(this);if(!n||j(n,o.hideClass.popup)){B("You're trying to update the closed or closing popup, that won't work. Use the update() method in preConfirm parameter or show a new popup.");return}let s=Hr(e),a=Object.assign({},o,s);xn(a),t.dataset.swal2Theme=a.theme,Qt(this,a),v.innerParams.set(this,a),Object.defineProperties(this,{params:{value:Object.assign({},this.params,e),writable:!1,enumerable:!0}})}var Hr=e=>{let t={};return Object.keys(e).forEach(n=>{kn(n)?t[n]=e[n]:B(`Invalid parameter to update: ${n}`)}),t};function Sn(){let e=v.domCache.get(this),t=v.innerParams.get(this);if(!t){Pn(this);return}e.popup&&w.swalCloseEventFinishedCallback&&(w.swalCloseEventFinishedCallback(),delete w.swalCloseEventFinishedCallback),typeof t.didDestroy=="function"&&t.didDestroy(),w.eventEmitter.emit("didDestroy"),_r(this)}var _r=e=>{Pn(e),delete e.params,delete w.keydownHandler,delete w.keydownTarget,delete w.currentInstance},Pn=e=>{e.isAwaitingPromise?(Ze(v,e),e.isAwaitingPromise=!0):(Ze(re,e),Ze(v,e),delete e.isAwaitingPromise,delete e.disableButtons,delete e.enableButtons,delete e.getInput,delete e.disableInput,delete e.enableInput,delete e.hideLoading,delete e.disableLoading,delete e.showValidationMessage,delete e.resetValidationMessage,delete e.close,delete e.closePopup,delete e.closeModal,delete e.closeToast,delete e.rejectPromise,delete e.update,delete e._destroy)},Ze=(e,t)=>{for(let n in e)e[n].delete(t)},Nr=Object.freeze({__proto__:null,_destroy:Sn,close:G,closeModal:G,closePopup:G,closeToast:G,disableButtons:wn,disableInput:hn,disableLoading:He,enableButtons:fn,enableInput:gn,getInput:dn,handleAwaitingPromise:xe,hideLoading:He,rejectPromise:an,resetValidationMessage:bn,showValidationMessage:yn,update:En}),Rr=(e,t,n)=>{e.toast?zr(e,t,n):(Fr(t),jr(t),Wr(e,t,n))},zr=(e,t,n)=>{t.popup.onclick=()=>{e&&(qr(e)||e.timer||e.input)||n(ce.close)}},qr=e=>!!(e.showConfirmButton||e.showDenyButton||e.showCancelButton||e.showCloseButton),_e=!1,Fr=e=>{e.popup.onmousedown=()=>{e.container.onmouseup=function(t){e.container.onmouseup=()=>{},t.target===e.container&&(_e=!0)}}},jr=e=>{e.container.onmousedown=t=>{t.target===e.container&&t.preventDefault(),e.popup.onmouseup=function(n){e.popup.onmouseup=()=>{},(n.target===e.popup||n.target instanceof HTMLElement&&e.popup.contains(n.target))&&(_e=!0)}}},Wr=(e,t,n)=>{t.container.onclick=o=>{if(_e){_e=!1;return}o.target===t.container&&Re(e.allowOutsideClick)&&n(ce.backdrop)}},Yr=e=>typeof e=="object"&&e.jquery,Mt=e=>e instanceof Element||Yr(e),Vr=e=>{let t={};return typeof e[0]=="object"&&!Mt(e[0])?Object.assign(t,e[0]):["title","html","icon"].forEach((n,o)=>{let s=e[o];typeof s=="string"||Mt(s)?t[n]=s:s!==void 0&&ee(`Unexpected type of ${n}! Expected "string" or "Element", got ${typeof s}`)}),t};function Ur(){for(var e=arguments.length,t=new Array(e),n=0;nw.timeout&&w.timeout.getTimerLeft(),An=()=>{if(w.timeout)return oo(),w.timeout.stop()},In=()=>{if(w.timeout){let e=w.timeout.start();return dt(e),e}},Xr=()=>{let e=w.timeout;return e&&(e.running?An():In())},Zr=e=>{if(w.timeout){let t=w.timeout.increase(e);return dt(t,!0),t}},Jr=()=>!!(w.timeout&&w.timeout.isRunning()),$t=!1,Qe={};function Qr(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:"data-swal-template";Qe[e]=this,$t||(document.body.addEventListener("click",es),$t=!0)}var es=e=>{for(let t=e.target;t&&t!==document;t=t.parentNode)for(let n in Qe){let o=t.getAttribute(n);if(o){Qe[n].fire({template:o});return}}},et=class{constructor(){this.events={}}_getHandlersByEventName(t){return typeof this.events[t]>"u"&&(this.events[t]=[]),this.events[t]}on(t,n){let o=this._getHandlersByEventName(t);o.includes(n)||o.push(n)}once(t,n){var o=this;let s=function(){o.removeListener(t,s);for(var a=arguments.length,d=new Array(a),m=0;m1?n-1:0),s=1;s{try{a.apply(this,o)}catch(d){console.error(d)}})}removeListener(t,n){let o=this._getHandlersByEventName(t),s=o.indexOf(n);s>-1&&o.splice(s,1)}removeAllListeners(t){this.events[t]!==void 0&&(this.events[t].length=0)}reset(){this.events={}}};w.eventEmitter=new et;var ts=(e,t)=>{w.eventEmitter.on(e,t)},ns=(e,t)=>{w.eventEmitter.once(e,t)},os=(e,t)=>{if(!e){w.eventEmitter.reset();return}t?w.eventEmitter.removeListener(e,t):w.eventEmitter.removeAllListeners(e)},rs=Object.freeze({__proto__:null,argsToParams:Vr,bindClickHandler:Qr,clickCancel:Vo,clickConfirm:en,clickDeny:Yo,enableLoading:se,fire:Ur,getActions:ve,getCancelButton:ie,getCloseButton:it,getConfirmButton:z,getContainer:L,getDenyButton:te,getFocusableElements:lt,getFooter:Ft,getHtmlContainer:st,getIcon:ae,getIconContent:Zn,getImage:qt,getInputLabel:Jn,getLoader:le,getPopup:y,getProgressSteps:at,getTimerLeft:Kr,getTimerProgressBar:qe,getTitle:zt,getValidationMessage:ze,increaseTimer:Zr,isDeprecatedParameter:Cn,isLoading:eo,isTimerRunning:Jr,isUpdatableParameter:kn,isValidParameter:vn,isVisible:Wo,mixin:Gr,off:os,on:ts,once:ns,resumeTimer:In,showLoading:se,stopTimer:An,toggleTimer:Xr}),tt=class{constructor(t,n){this.callback=t,this.remaining=n,this.running=!1,this.start()}start(){return this.running||(this.running=!0,this.started=new Date,this.id=setTimeout(this.callback,this.remaining)),this.remaining}stop(){return this.started&&this.running&&(this.running=!1,clearTimeout(this.id),this.remaining-=new Date().getTime()-this.started.getTime()),this.remaining}increase(t){let n=this.running;return n&&this.stop(),this.remaining+=t,n&&this.start(),this.remaining}getTimerLeft(){return this.running&&(this.stop(),this.start()),this.remaining}isRunning(){return this.running}},Tn=["swal-title","swal-html","swal-footer"],ss=e=>{let t=typeof e.template=="string"?document.querySelector(e.template):e.template;if(!t)return{};let n=t.content;return ms(n),Object.assign(as(n),is(n),ls(n),cs(n),us(n),ds(n),ps(n,Tn))},as=e=>{let t={};return Array.from(e.querySelectorAll("swal-param")).forEach(o=>{J(o,["name","value"]);let s=o.getAttribute("name"),a=o.getAttribute("value");!s||!a||(typeof oe[s]=="boolean"?t[s]=a!=="false":typeof oe[s]=="object"?t[s]=JSON.parse(a):t[s]=a)}),t},is=e=>{let t={};return Array.from(e.querySelectorAll("swal-function-param")).forEach(o=>{let s=o.getAttribute("name"),a=o.getAttribute("value");!s||!a||(t[s]=new Function(`return ${a}`)())}),t},ls=e=>{let t={};return Array.from(e.querySelectorAll("swal-button")).forEach(o=>{J(o,["type","color","aria-label"]);let s=o.getAttribute("type");!s||!["confirm","cancel","deny"].includes(s)||(t[`${s}ButtonText`]=o.innerHTML,t[`show${nt(s)}Button`]=!0,o.hasAttribute("color")&&(t[`${s}ButtonColor`]=o.getAttribute("color")),o.hasAttribute("aria-label")&&(t[`${s}ButtonAriaLabel`]=o.getAttribute("aria-label")))}),t},cs=e=>{let t={},n=e.querySelector("swal-image");return n&&(J(n,["src","width","height","alt"]),n.hasAttribute("src")&&(t.imageUrl=n.getAttribute("src")||void 0),n.hasAttribute("width")&&(t.imageWidth=n.getAttribute("width")||void 0),n.hasAttribute("height")&&(t.imageHeight=n.getAttribute("height")||void 0),n.hasAttribute("alt")&&(t.imageAlt=n.getAttribute("alt")||void 0)),t},us=e=>{let t={},n=e.querySelector("swal-icon");return n&&(J(n,["type","color"]),n.hasAttribute("type")&&(t.icon=n.getAttribute("type")),n.hasAttribute("color")&&(t.iconColor=n.getAttribute("color")),t.iconHtml=n.innerHTML),t},ds=e=>{let t={},n=e.querySelector("swal-input");n&&(J(n,["type","label","placeholder","value"]),t.input=n.getAttribute("type")||"text",n.hasAttribute("label")&&(t.inputLabel=n.getAttribute("label")),n.hasAttribute("placeholder")&&(t.inputPlaceholder=n.getAttribute("placeholder")),n.hasAttribute("value")&&(t.inputValue=n.getAttribute("value")));let o=Array.from(e.querySelectorAll("swal-input-option"));return o.length&&(t.inputOptions={},o.forEach(s=>{J(s,["value"]);let a=s.getAttribute("value");if(!a)return;let d=s.innerHTML;t.inputOptions[a]=d})),t},ps=(e,t)=>{let n={};for(let o in t){let s=t[o],a=e.querySelector(s);a&&(J(a,[]),n[s.replace(/^swal-/,"")]=a.innerHTML.trim())}return n},ms=e=>{let t=Tn.concat(["swal-param","swal-function-param","swal-button","swal-image","swal-icon","swal-input","swal-input-option"]);Array.from(e.children).forEach(n=>{let o=n.tagName.toLowerCase();t.includes(o)||B(`Unrecognized element <${o}>`)})},J=(e,t)=>{Array.from(e.attributes).forEach(n=>{t.indexOf(n.name)===-1&&B([`Unrecognized attribute "${n.name}" on <${e.tagName.toLowerCase()}>.`,`${t.length?`Allowed attributes are: ${t.join(", ")}`:"To set the value, use HTML within the element."}`])})},Dn=10,fs=e=>{let t=L(),n=y();typeof e.willOpen=="function"&&e.willOpen(n),w.eventEmitter.emit("willOpen",n);let s=window.getComputedStyle(document.body).overflowY;hs(t,n,e),setTimeout(()=>{ws(t,n)},Dn),ct()&&(gs(t,e.scrollbarPadding,s),er()),!Fe()&&!w.previousActiveElement&&(w.previousActiveElement=document.activeElement),typeof e.didOpen=="function"&&setTimeout(()=>e.didOpen(n)),w.eventEmitter.emit("didOpen",n),N(t,i["no-transition"])},Ne=e=>{let t=y();if(e.target!==t)return;let n=L();t.removeEventListener("animationend",Ne),t.removeEventListener("transitionend",Ne),n.style.overflowY="auto"},ws=(e,t)=>{Yt(t)?(e.style.overflowY="hidden",t.addEventListener("animationend",Ne),t.addEventListener("transitionend",Ne)):e.style.overflowY="auto"},gs=(e,t,n)=>{tr(),t&&n!=="hidden"&&lr(n),setTimeout(()=>{e.scrollTop=0})},hs=(e,t,n)=>{h(e,n.showClass.backdrop),n.animation?(t.style.setProperty("opacity","0","important"),A(t,"grid"),setTimeout(()=>{h(t,n.showClass.popup),t.style.removeProperty("opacity")},Dn)):A(t,"grid"),h([document.documentElement,document.body],i.shown),n.heightAuto&&n.backdrop&&!n.toast&&h([document.documentElement,document.body],i["height-auto"])},Ot={email:(e,t)=>/^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(e)?Promise.resolve():Promise.resolve(t||"Invalid email address"),url:(e,t)=>/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-z]{2,63}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/.test(e)?Promise.resolve():Promise.resolve(t||"Invalid URL")};function ys(e){e.inputValidator||(e.input==="email"&&(e.inputValidator=Ot.email),e.input==="url"&&(e.inputValidator=Ot.url))}function bs(e){(!e.target||typeof e.target=="string"&&!document.querySelector(e.target)||typeof e.target!="string"&&!e.target.appendChild)&&(B('Target parameter is not valid, defaulting to "body"'),e.target="body")}function vs(e){ys(e),e.showLoaderOnConfirm&&!e.preConfirm&&B(`showLoaderOnConfirm is set to true, but preConfirm is not defined. showLoaderOnConfirm should be used together with preConfirm, see usage example: -https://sweetalert2.github.io/#ajax-request`),ks(e),typeof e.title=="string"&&(e.title=e.title.split(` -`).join("
      ")),fo(e)}var R,Te=new WeakMap,x=class{constructor(){if(Yn(this,Te,void 0),typeof window>"u")return;R=this;for(var t=arguments.length,n=new Array(t),o=0;o1&&arguments[1]!==void 0?arguments[1]:{};if(En(Object.assign({},n,t)),w.currentInstance){let a=se.swalPromiseResolve.get(w.currentInstance),{isAwaitingPromise:d}=w.currentInstance;w.currentInstance._destroy(),d||a({isDismissed:!0}),ct()&&rn()}w.currentInstance=R;let o=Es(t,n);Cs(o),Object.freeze(o),w.timeout&&(w.timeout.stop(),delete w.timeout),clearTimeout(w.restoreFocusTimeout);let s=Ss(R);return en(R,o),v.innerParams.set(R,o),xs(R,s,o)}then(t){return St(Te,this).then(t)}finally(t){return St(Te,this).finally(t)}},xs=(e,t,n)=>new Promise((o,s)=>{let a=d=>{e.close({isDismissed:!0,dismiss:d})};se.swalPromiseResolve.set(e,o),se.swalPromiseReject.set(e,s),t.confirmButton.onclick=()=>{Ar(e)},t.denyButton.onclick=()=>{Ir(e)},t.cancelButton.onclick=()=>{Tr(e,a)},t.closeButton.onclick=()=>{a(ue.close)},qr(n,t,a),Ko(w,n,a),yr(e,n),gs(n),Ps(w,n,a),As(t,n),setTimeout(()=>{t.container.scrollTop=0})}),Es=(e,t)=>{let n=is(e),o=Object.assign({},re,t,n,e);return o.showClass=Object.assign({},re.showClass,o.showClass),o.hideClass=Object.assign({},re.hideClass,o.hideClass),o.animation===!1&&(o.showClass={backdrop:"swal2-noanimation"},o.hideClass={}),o},Ss=e=>{let t={popup:y(),container:L(),actions:ve(),confirmButton:z(),denyButton:ne(),cancelButton:le(),loader:ce(),closeButton:it(),validationMessage:ze(),progressSteps:at()};return v.domCache.set(e,t),t},Ps=(e,t,n)=>{let o=qe();D(o),t.timer&&(e.timeout=new tt(()=>{n("timer"),delete e.timeout},t.timer),t.timerProgressBar&&(A(o),O(o,t,"timerProgressBar"),setTimeout(()=>{e.timeout&&e.timeout.running&&dt(t.timer)})))},As=(e,t)=>{if(!t.toast){if(!Re(t.allowEnterKey)){zt("allowEnterKey"),Ds();return}Is(e)||Ts(e,t)||Je(-1,1)}},Is=e=>{let t=Array.from(e.popup.querySelectorAll("[autofocus]"));for(let n of t)if(n instanceof HTMLElement&&M(n))return n.focus(),!0;return!1},Ts=(e,t)=>t.focusDeny&&M(e.denyButton)?(e.denyButton.focus(),!0):t.focusCancel&&M(e.cancelButton)?(e.cancelButton.focus(),!0):t.focusConfirm&&M(e.confirmButton)?(e.confirmButton.focus(),!0):!1,Ds=()=>{document.activeElement instanceof HTMLElement&&typeof document.activeElement.blur=="function"&&document.activeElement.blur()};x.prototype.disableButtons=gn;x.prototype.enableButtons=wn;x.prototype.getInput=pn;x.prototype.disableInput=yn;x.prototype.enableInput=hn;x.prototype.hideLoading=He;x.prototype.disableLoading=He;x.prototype.showValidationMessage=bn;x.prototype.resetValidationMessage=vn;x.prototype.close=G;x.prototype.closePopup=G;x.prototype.closeModal=G;x.prototype.closeToast=G;x.prototype.rejectPromise=ln;x.prototype.update=Sn;x.prototype._destroy=Pn;Object.assign(x,as);Object.keys(zr).forEach(e=>{x[e]=function(){return R&&R[e]?R[e](...arguments):null}});x.DismissReason=ue;x.version="11.18.0";var ee=x;ee.default=ee;typeof document<"u"&&(function(e,t){var n=e.createElement("style");if(e.getElementsByTagName("head")[0].appendChild(n),n.styleSheet)n.styleSheet.disabled||(n.styleSheet.cssText=t);else try{n.innerHTML=t}catch{n.innerText=t}})(document,':root{--swal2-container-padding: 0.625em;--swal2-backdrop: rgba(0, 0, 0, 0.4);--swal2-width: 32em;--swal2-padding: 0 0 1.25em;--swal2-border: none;--swal2-border-radius: 0.3125rem;--swal2-background: white;--swal2-color: #545454;--swal2-footer-border-color: #eee;--swal2-show-animation: swal2-show 0.3s;--swal2-hide-animation: swal2-hide 0.15s forwards;--swal2-title-padding: 0.8em 1em 0;--swal2-html-container-padding: 1em 1.6em 0.3em;--swal2-input-background: transparent;--swal2-progress-step-background: #add8e6;--swal2-validation-message-background: #f0f0f0;--swal2-validation-message-color: #666;--swal2-close-button-position: initial;--swal2-close-button-inset: auto;--swal2-close-button-font-size: 2.5em;--swal2-close-button-color: #ccc;--swal2-close-button-transition: color 0.1s, box-shadow 0.1s;--swal2-close-button-outline: initial;--swal2-close-button-hover-transform: none}[data-swal2-theme=dark]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white)}@media(prefers-color-scheme: dark){[data-swal2-theme=auto]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white)}}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto !important}body.swal2-no-backdrop .swal2-container{background-color:rgba(0,0,0,0) !important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:all}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px var(--swal2-backdrop)}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:rgba(0,0,0,0);pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{inset:0 auto auto 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{inset:0 0 auto auto}body.swal2-toast-shown .swal2-container.swal2-top-start,body.swal2-toast-shown .swal2-container.swal2-top-left{inset:0 auto auto 0}body.swal2-toast-shown .swal2-container.swal2-center-start,body.swal2-toast-shown .swal2-container.swal2-center-left{inset:50% auto auto 0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{inset:50% auto auto 50%;transform:translate(-50%, -50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{inset:50% 0 auto auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-start,body.swal2-toast-shown .swal2-container.swal2-bottom-left{inset:auto auto 0 0}body.swal2-toast-shown .swal2-container.swal2-bottom{inset:auto auto 0 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{inset:auto 0 0 auto}@media print{body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow-y:scroll !important}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown) .swal2-container{position:static !important}}div:where(.swal2-container){display:grid;position:fixed;z-index:1060;inset:0;box-sizing:border-box;grid-template-areas:"top-start top top-end" "center-start center center-end" "bottom-start bottom-center bottom-end";grid-template-rows:minmax(min-content, auto) minmax(min-content, auto) minmax(min-content, auto);height:100%;padding:var(--swal2-container-padding);overflow-x:hidden;transition:background-color .1s;-webkit-overflow-scrolling:touch}div:where(.swal2-container).swal2-backdrop-show,div:where(.swal2-container).swal2-noanimation{background:var(--swal2-backdrop)}div:where(.swal2-container).swal2-backdrop-hide{background:rgba(0,0,0,0) !important}div:where(.swal2-container).swal2-top-start,div:where(.swal2-container).swal2-center-start,div:where(.swal2-container).swal2-bottom-start{grid-template-columns:minmax(0, 1fr) auto auto}div:where(.swal2-container).swal2-top,div:where(.swal2-container).swal2-center,div:where(.swal2-container).swal2-bottom{grid-template-columns:auto minmax(0, 1fr) auto}div:where(.swal2-container).swal2-top-end,div:where(.swal2-container).swal2-center-end,div:where(.swal2-container).swal2-bottom-end{grid-template-columns:auto auto minmax(0, 1fr)}div:where(.swal2-container).swal2-top-start>.swal2-popup{align-self:start}div:where(.swal2-container).swal2-top>.swal2-popup{grid-column:2;place-self:start center}div:where(.swal2-container).swal2-top-end>.swal2-popup,div:where(.swal2-container).swal2-top-right>.swal2-popup{grid-column:3;place-self:start end}div:where(.swal2-container).swal2-center-start>.swal2-popup,div:where(.swal2-container).swal2-center-left>.swal2-popup{grid-row:2;align-self:center}div:where(.swal2-container).swal2-center>.swal2-popup{grid-column:2;grid-row:2;place-self:center center}div:where(.swal2-container).swal2-center-end>.swal2-popup,div:where(.swal2-container).swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;place-self:center end}div:where(.swal2-container).swal2-bottom-start>.swal2-popup,div:where(.swal2-container).swal2-bottom-left>.swal2-popup{grid-column:1;grid-row:3;align-self:end}div:where(.swal2-container).swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;place-self:end center}div:where(.swal2-container).swal2-bottom-end>.swal2-popup,div:where(.swal2-container).swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;place-self:end end}div:where(.swal2-container).swal2-grow-row>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-column:1/4;width:100%}div:where(.swal2-container).swal2-grow-column>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}div:where(.swal2-container).swal2-no-transition{transition:none !important}div:where(.swal2-container) div:where(.swal2-popup){display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0, 100%);width:var(--swal2-width);max-width:100%;padding:var(--swal2-padding);border:var(--swal2-border);border-radius:var(--swal2-border-radius);background:var(--swal2-background);color:var(--swal2-color);font-family:inherit;font-size:1rem}div:where(.swal2-container) div:where(.swal2-popup):focus{outline:none}div:where(.swal2-container) div:where(.swal2-popup).swal2-loading{overflow-y:hidden}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable{cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable div:where(.swal2-icon){cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging{cursor:grabbing}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging div:where(.swal2-icon){cursor:grabbing}div:where(.swal2-container) h2:where(.swal2-title){position:relative;max-width:100%;margin:0;padding:var(--swal2-title-padding);color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;word-wrap:break-word;cursor:initial}div:where(.swal2-container) div:where(.swal2-actions){display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:center;width:auto;margin:1.25em auto 0;padding:0}div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled[disabled]{opacity:.4}div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled:hover{background-image:linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1))}div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled:active{background-image:linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2))}div:where(.swal2-container) div:where(.swal2-loader){display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 rgba(0,0,0,0) #2778c4 rgba(0,0,0,0)}div:where(.swal2-container) button:where(.swal2-styled){margin:.3125em;padding:.625em 1.1em;transition:box-shadow .1s;box-shadow:0 0 0 3px rgba(0,0,0,0);font-weight:500}div:where(.swal2-container) button:where(.swal2-styled):not([disabled]){cursor:pointer}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm){border:0;border-radius:.25em;background:initial;background-color:#7066e0;color:#fff;font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):focus-visible{box-shadow:0 0 0 3px rgba(112,102,224,.5)}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny){border:0;border-radius:.25em;background:initial;background-color:#dc3741;color:#fff;font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):focus-visible{box-shadow:0 0 0 3px rgba(220,55,65,.5)}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel){border:0;border-radius:.25em;background:initial;background-color:#6e7881;color:#fff;font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):focus-visible{box-shadow:0 0 0 3px rgba(110,120,129,.5)}div:where(.swal2-container) button:where(.swal2-styled).swal2-default-outline:focus-visible{box-shadow:0 0 0 3px rgba(100,150,200,.5)}div:where(.swal2-container) button:where(.swal2-styled):focus-visible{outline:none}div:where(.swal2-container) button:where(.swal2-styled)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-footer){margin:1em 0 0;padding:1em 1em 0;border-top:1px solid var(--swal2-footer-border-color);color:inherit;font-size:1em;text-align:center;cursor:initial}div:where(.swal2-container) .swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto !important;overflow:hidden;border-bottom-right-radius:var(--swal2-border-radius);border-bottom-left-radius:var(--swal2-border-radius)}div:where(.swal2-container) div:where(.swal2-timer-progress-bar){width:100%;height:.25em;background:rgba(0,0,0,.2)}div:where(.swal2-container) img:where(.swal2-image){max-width:100%;margin:2em auto 1em;cursor:initial}div:where(.swal2-container) button:where(.swal2-close){position:var(--swal2-close-button-position);inset:var(--swal2-close-button-inset);z-index:2;align-items:center;justify-content:center;width:1.2em;height:1.2em;margin-top:0;margin-right:0;margin-bottom:-1.2em;padding:0;overflow:hidden;transition:var(--swal2-close-button-transition);border:none;border-radius:var(--swal2-border-radius);outline:var(--swal2-close-button-outline);background:rgba(0,0,0,0);color:var(--swal2-close-button-color);font-family:monospace;font-size:var(--swal2-close-button-font-size);cursor:pointer;justify-self:end}div:where(.swal2-container) button:where(.swal2-close):hover{transform:var(--swal2-close-button-hover-transform);background:rgba(0,0,0,0);color:#f27474}div:where(.swal2-container) button:where(.swal2-close):focus-visible{outline:none;box-shadow:inset 0 0 0 3px rgba(100,150,200,.5)}div:where(.swal2-container) button:where(.swal2-close)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-html-container){z-index:1;justify-content:center;margin:0;padding:var(--swal2-html-container-padding);overflow:auto;color:inherit;font-size:1.125em;font-weight:normal;line-height:normal;text-align:center;word-wrap:break-word;word-break:break-word;cursor:initial}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea),div:where(.swal2-container) select:where(.swal2-select),div:where(.swal2-container) div:where(.swal2-radio),div:where(.swal2-container) label:where(.swal2-checkbox){margin:1em 2em 3px}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea){box-sizing:border-box;width:auto;transition:border-color .1s,box-shadow .1s;border:1px solid #d9d9d9;border-radius:.1875em;background:var(--swal2-input-background);box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px rgba(0,0,0,0);color:inherit;font-size:1.125em}div:where(.swal2-container) input:where(.swal2-input).swal2-inputerror,div:where(.swal2-container) input:where(.swal2-file).swal2-inputerror,div:where(.swal2-container) textarea:where(.swal2-textarea).swal2-inputerror{border-color:#f27474 !important;box-shadow:0 0 2px #f27474 !important}div:where(.swal2-container) input:where(.swal2-input):focus,div:where(.swal2-container) input:where(.swal2-file):focus,div:where(.swal2-container) textarea:where(.swal2-textarea):focus{border:1px solid #b4dbed;outline:none;box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px rgba(100,150,200,.5)}div:where(.swal2-container) input:where(.swal2-input)::placeholder,div:where(.swal2-container) input:where(.swal2-file)::placeholder,div:where(.swal2-container) textarea:where(.swal2-textarea)::placeholder{color:#ccc}div:where(.swal2-container) .swal2-range{margin:1em 2em 3px;background:var(--swal2-background)}div:where(.swal2-container) .swal2-range input{width:80%}div:where(.swal2-container) .swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}div:where(.swal2-container) .swal2-range input,div:where(.swal2-container) .swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}div:where(.swal2-container) .swal2-input{height:2.625em;padding:0 .75em}div:where(.swal2-container) .swal2-file{width:75%;margin-right:auto;margin-left:auto;background:var(--swal2-input-background);font-size:1.125em}div:where(.swal2-container) .swal2-textarea{height:6.75em;padding:.75em}div:where(.swal2-container) .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:var(--swal2-input-background);color:inherit;font-size:1.125em}div:where(.swal2-container) .swal2-radio,div:where(.swal2-container) .swal2-checkbox{align-items:center;justify-content:center;background:var(--swal2-background);color:inherit}div:where(.swal2-container) .swal2-radio label,div:where(.swal2-container) .swal2-checkbox label{margin:0 .6em;font-size:1.125em}div:where(.swal2-container) .swal2-radio input,div:where(.swal2-container) .swal2-checkbox input{flex-shrink:0;margin:0 .4em}div:where(.swal2-container) label:where(.swal2-input-label){display:flex;justify-content:center;margin:1em auto 0}div:where(.swal2-container) div:where(.swal2-validation-message){align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:var(--swal2-validation-message-background);color:var(--swal2-validation-message-color);font-size:1em;font-weight:300}div:where(.swal2-container) div:where(.swal2-validation-message)::before{content:"!";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}div:where(.swal2-container) .swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:rgba(0,0,0,0);font-weight:600}div:where(.swal2-container) .swal2-progress-steps li{display:inline-block;position:relative}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:var(--swal2-progress-step-background);color:#fff}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:var(--swal2-progress-step-background)}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}div:where(.swal2-icon){position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;border:.25em solid rgba(0,0,0,0);border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;user-select:none}div:where(.swal2-icon) .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}div:where(.swal2-icon).swal2-error{border-color:#f27474;color:#f27474}div:where(.swal2-icon).swal2-error .swal2-x-mark{position:relative;flex-grow:1}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}div:where(.swal2-icon).swal2-warning{border-color:#f8bb86;color:#f8bb86}div:where(.swal2-icon).swal2-warning.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-warning.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .5s}div:where(.swal2-icon).swal2-info{border-color:#3fc3ee;color:#3fc3ee}div:where(.swal2-icon).swal2-info.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-info.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .8s}div:where(.swal2-icon).swal2-question{border-color:#87adbd;color:#87adbd}div:where(.swal2-icon).swal2-question.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-question.swal2-icon-show .swal2-icon-content{animation:swal2-animate-question-mark .8s}div:where(.swal2-icon).swal2-success{border-color:#a5dc86;color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;border-radius:50%}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}div:where(.swal2-icon).swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-0.25em;left:-0.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}div:where(.swal2-icon).swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}[class^=swal2]{-webkit-tap-highlight-color:rgba(0,0,0,0)}.swal2-show{animation:var(--swal2-show-animation)}.swal2-hide{animation:var(--swal2-hide-animation)}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{margin-right:initial;margin-left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}.swal2-toast{box-sizing:border-box;grid-column:1/4 !important;grid-row:1/4 !important;grid-template-columns:min-content auto min-content;padding:1em;overflow-y:hidden;background:var(--swal2-background);box-shadow:0 0 1px rgba(0,0,0,.075),0 1px 2px rgba(0,0,0,.075),1px 2px 4px rgba(0,0,0,.075),1px 3px 8px rgba(0,0,0,.075),2px 4px 16px rgba(0,0,0,.075);pointer-events:all}.swal2-toast>*{grid-column:2}.swal2-toast h2:where(.swal2-title){margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-toast .swal2-loading{justify-content:center}.swal2-toast input:where(.swal2-input){height:2em;margin:.5em;font-size:1em}.swal2-toast .swal2-validation-message{font-size:1em}.swal2-toast div:where(.swal2-footer){margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-toast button:where(.swal2-close){grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-toast div:where(.swal2-html-container){margin:.5em 1em;padding:0;overflow:initial;font-size:1em;text-align:initial}.swal2-toast div:where(.swal2-html-container):empty{padding:0}.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-toast .swal2-icon{grid-column:1;grid-row:1/99;align-self:center;width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:bold}.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-toast div:where(.swal2-actions){justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-toast button:where(.swal2-styled){margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;border-radius:50%}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.8em;left:-0.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}.swal2-toast.swal2-show{animation:swal2-toast-show .5s}.swal2-toast.swal2-hide{animation:swal2-toast-hide .1s forwards}@keyframes swal2-show{0%{transform:scale(0.7)}45%{transform:scale(1.05)}80%{transform:scale(0.95)}100%{transform:scale(1)}}@keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(0.5);opacity:0}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-0.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(0.4);opacity:0}50%{margin-top:1.625em;transform:scale(0.4);opacity:0}80%{margin-top:-0.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);opacity:1}}@keyframes swal2-rotate-loading{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}25%{transform:rotateZ(-25deg);opacity:.4}50%{transform:rotateZ(15deg);opacity:.8}75%{transform:rotateZ(-5deg);opacity:1}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-toast-show{0%{transform:translateY(-0.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(0.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0deg)}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-0.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}');var g=ee,K=g.mixin({input:"text",showCancelButton:!0,showConfirmButton:!0,toast:!1}),b=K.mixin({toast:!1,input:"number"}),l=g.mixin({toast:!0,position:"bottom"}),E=g.mixin({icon:"warning",showCancelButton:!0,toast:!1,confirmButtonText:"Confirm",cancelButtonText:"Cancel"}),Ns=g.mixin({icon:"info",showCancelButton:!1,toast:!1});window.Swal=g;function Ln(){fetch(`https://raw.githubusercontent.com/ProdigyPXP/ProdigyOrigin/master/originGUI/statusmessage.json?updated=${Date.now()}`).then(e=>e.json()).then(async e=>{if(e.enabled===!1)return console.log("Status message is disabled.");await g.fire({title:e.title,html:e.html,icon:e.icon})})}var pe=document.createElement("div"),We=document.getElementById("game-wrapper");document.getElementById("origin-menu")?.remove();document.getElementById("origin-toggler")?.remove();pe.id="origin-menu";pe.style="position: fixed;top: -10%;left: 10%;right: 10%;width: 80%;height: 80%;z-index: 2;background-color: rgba(0, 0, 0, 0.5);backdrop-filter: blur(5px);";We?.prepend(pe);var de=document.createElement("button");de.id="origin-toggler";var ht=!1;We?.prepend(de);de.onclick=()=>{ht=!ht,ht?(de.innerText="▼",pe.style.top="-100vh"):(de.innerText="▲",pe.style.top="10%")};de.onclick({});var me=document.createElement("DIV");me.classList.add("menu-left");pe.append(me);var Mn=!0;function q(e){let t=document.createElement("div");Mn==!1?(t.append(document.createElement("br")),t.append(document.createElement("br"))):Mn=!1,t.classList.add("menu-area"),t.style.textAlign="center",me.append(t);let n=document.createElement("h1");return n.innerText=e,n.style.textAlign="center",n.style.color="white",t.append(n),t}var Ye=document.createElement("h1");Ye.classList.add("menu-title");Ye.innerText="Play Origin";Ye.style.textAlign="center";me.append(Ye);var Ve=document.createElement("h2");Ve.style.fontSize="25px";Ve.style.color="white";Ve.innerHTML="
      Press SHIFT to show/hide the menu. Scroll down in the menu for more mods.";me.append(Ve);var Ue=document.createElement("h3");Ue.style.fontSize="20px";Ue.innerHTML=` +https://sweetalert2.github.io/#ajax-request`),bs(e),typeof e.title=="string"&&(e.title=e.title.split(` +`).join("
      ")),po(e)}var R,Te=new WeakMap,x=class{constructor(){if(jn(this,Te,void 0),typeof window>"u")return;R=this;for(var t=arguments.length,n=new Array(t),o=0;o1&&arguments[1]!==void 0?arguments[1]:{};if(xn(Object.assign({},n,t)),w.currentInstance){let a=re.swalPromiseResolve.get(w.currentInstance),{isAwaitingPromise:d}=w.currentInstance;w.currentInstance._destroy(),d||a({isDismissed:!0}),ct()&&on()}w.currentInstance=R;let o=Cs(t,n);vs(o),Object.freeze(o),w.timeout&&(w.timeout.stop(),delete w.timeout),clearTimeout(w.restoreFocusTimeout);let s=xs(R);return Qt(R,o),v.innerParams.set(R,o),ks(R,s,o)}then(t){return Et(Te,this).then(t)}finally(t){return Et(Te,this).finally(t)}},ks=(e,t,n)=>new Promise((o,s)=>{let a=d=>{e.close({isDismissed:!0,dismiss:d})};re.swalPromiseResolve.set(e,o),re.swalPromiseReject.set(e,s),t.confirmButton.onclick=()=>{Sr(e)},t.denyButton.onclick=()=>{Pr(e)},t.cancelButton.onclick=()=>{Ar(e,a)},t.closeButton.onclick=()=>{a(ce.close)},Rr(n,t,a),Uo(w,n,a),gr(e,n),fs(n),Es(w,n,a),Ss(t,n),setTimeout(()=>{t.container.scrollTop=0})}),Cs=(e,t)=>{let n=ss(e),o=Object.assign({},oe,t,n,e);return o.showClass=Object.assign({},oe.showClass,o.showClass),o.hideClass=Object.assign({},oe.hideClass,o.hideClass),o.animation===!1&&(o.showClass={backdrop:"swal2-noanimation"},o.hideClass={}),o},xs=e=>{let t={popup:y(),container:L(),actions:ve(),confirmButton:z(),denyButton:te(),cancelButton:ie(),loader:le(),closeButton:it(),validationMessage:ze(),progressSteps:at()};return v.domCache.set(e,t),t},Es=(e,t,n)=>{let o=qe();D(o),t.timer&&(e.timeout=new tt(()=>{n("timer"),delete e.timeout},t.timer),t.timerProgressBar&&(A(o),O(o,t,"timerProgressBar"),setTimeout(()=>{e.timeout&&e.timeout.running&&dt(t.timer)})))},Ss=(e,t)=>{if(!t.toast){if(!Re(t.allowEnterKey)){Rt("allowEnterKey"),Is();return}Ps(e)||As(e,t)||Je(-1,1)}},Ps=e=>{let t=Array.from(e.popup.querySelectorAll("[autofocus]"));for(let n of t)if(n instanceof HTMLElement&&M(n))return n.focus(),!0;return!1},As=(e,t)=>t.focusDeny&&M(e.denyButton)?(e.denyButton.focus(),!0):t.focusCancel&&M(e.cancelButton)?(e.cancelButton.focus(),!0):t.focusConfirm&&M(e.confirmButton)?(e.confirmButton.focus(),!0):!1,Is=()=>{document.activeElement instanceof HTMLElement&&typeof document.activeElement.blur=="function"&&document.activeElement.blur()};x.prototype.disableButtons=wn;x.prototype.enableButtons=fn;x.prototype.getInput=dn;x.prototype.disableInput=hn;x.prototype.enableInput=gn;x.prototype.hideLoading=He;x.prototype.disableLoading=He;x.prototype.showValidationMessage=yn;x.prototype.resetValidationMessage=bn;x.prototype.close=G;x.prototype.closePopup=G;x.prototype.closeModal=G;x.prototype.closeToast=G;x.prototype.rejectPromise=an;x.prototype.update=En;x.prototype._destroy=Sn;Object.assign(x,rs);Object.keys(Nr).forEach(e=>{x[e]=function(){return R&&R[e]?R[e](...arguments):null}});x.DismissReason=ce;x.version="11.18.0";var Q=x;Q.default=Q;typeof document<"u"&&(function(e,t){var n=e.createElement("style");if(e.getElementsByTagName("head")[0].appendChild(n),n.styleSheet)n.styleSheet.disabled||(n.styleSheet.cssText=t);else try{n.innerHTML=t}catch{n.innerText=t}})(document,':root{--swal2-container-padding: 0.625em;--swal2-backdrop: rgba(0, 0, 0, 0.4);--swal2-width: 32em;--swal2-padding: 0 0 1.25em;--swal2-border: none;--swal2-border-radius: 0.3125rem;--swal2-background: white;--swal2-color: #545454;--swal2-footer-border-color: #eee;--swal2-show-animation: swal2-show 0.3s;--swal2-hide-animation: swal2-hide 0.15s forwards;--swal2-title-padding: 0.8em 1em 0;--swal2-html-container-padding: 1em 1.6em 0.3em;--swal2-input-background: transparent;--swal2-progress-step-background: #add8e6;--swal2-validation-message-background: #f0f0f0;--swal2-validation-message-color: #666;--swal2-close-button-position: initial;--swal2-close-button-inset: auto;--swal2-close-button-font-size: 2.5em;--swal2-close-button-color: #ccc;--swal2-close-button-transition: color 0.1s, box-shadow 0.1s;--swal2-close-button-outline: initial;--swal2-close-button-hover-transform: none}[data-swal2-theme=dark]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white)}@media(prefers-color-scheme: dark){[data-swal2-theme=auto]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white)}}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto !important}body.swal2-no-backdrop .swal2-container{background-color:rgba(0,0,0,0) !important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:all}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px var(--swal2-backdrop)}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:rgba(0,0,0,0);pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{inset:0 auto auto 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{inset:0 0 auto auto}body.swal2-toast-shown .swal2-container.swal2-top-start,body.swal2-toast-shown .swal2-container.swal2-top-left{inset:0 auto auto 0}body.swal2-toast-shown .swal2-container.swal2-center-start,body.swal2-toast-shown .swal2-container.swal2-center-left{inset:50% auto auto 0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{inset:50% auto auto 50%;transform:translate(-50%, -50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{inset:50% 0 auto auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-start,body.swal2-toast-shown .swal2-container.swal2-bottom-left{inset:auto auto 0 0}body.swal2-toast-shown .swal2-container.swal2-bottom{inset:auto auto 0 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{inset:auto 0 0 auto}@media print{body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow-y:scroll !important}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown) .swal2-container{position:static !important}}div:where(.swal2-container){display:grid;position:fixed;z-index:1060;inset:0;box-sizing:border-box;grid-template-areas:"top-start top top-end" "center-start center center-end" "bottom-start bottom-center bottom-end";grid-template-rows:minmax(min-content, auto) minmax(min-content, auto) minmax(min-content, auto);height:100%;padding:var(--swal2-container-padding);overflow-x:hidden;transition:background-color .1s;-webkit-overflow-scrolling:touch}div:where(.swal2-container).swal2-backdrop-show,div:where(.swal2-container).swal2-noanimation{background:var(--swal2-backdrop)}div:where(.swal2-container).swal2-backdrop-hide{background:rgba(0,0,0,0) !important}div:where(.swal2-container).swal2-top-start,div:where(.swal2-container).swal2-center-start,div:where(.swal2-container).swal2-bottom-start{grid-template-columns:minmax(0, 1fr) auto auto}div:where(.swal2-container).swal2-top,div:where(.swal2-container).swal2-center,div:where(.swal2-container).swal2-bottom{grid-template-columns:auto minmax(0, 1fr) auto}div:where(.swal2-container).swal2-top-end,div:where(.swal2-container).swal2-center-end,div:where(.swal2-container).swal2-bottom-end{grid-template-columns:auto auto minmax(0, 1fr)}div:where(.swal2-container).swal2-top-start>.swal2-popup{align-self:start}div:where(.swal2-container).swal2-top>.swal2-popup{grid-column:2;place-self:start center}div:where(.swal2-container).swal2-top-end>.swal2-popup,div:where(.swal2-container).swal2-top-right>.swal2-popup{grid-column:3;place-self:start end}div:where(.swal2-container).swal2-center-start>.swal2-popup,div:where(.swal2-container).swal2-center-left>.swal2-popup{grid-row:2;align-self:center}div:where(.swal2-container).swal2-center>.swal2-popup{grid-column:2;grid-row:2;place-self:center center}div:where(.swal2-container).swal2-center-end>.swal2-popup,div:where(.swal2-container).swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;place-self:center end}div:where(.swal2-container).swal2-bottom-start>.swal2-popup,div:where(.swal2-container).swal2-bottom-left>.swal2-popup{grid-column:1;grid-row:3;align-self:end}div:where(.swal2-container).swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;place-self:end center}div:where(.swal2-container).swal2-bottom-end>.swal2-popup,div:where(.swal2-container).swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;place-self:end end}div:where(.swal2-container).swal2-grow-row>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-column:1/4;width:100%}div:where(.swal2-container).swal2-grow-column>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}div:where(.swal2-container).swal2-no-transition{transition:none !important}div:where(.swal2-container) div:where(.swal2-popup){display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0, 100%);width:var(--swal2-width);max-width:100%;padding:var(--swal2-padding);border:var(--swal2-border);border-radius:var(--swal2-border-radius);background:var(--swal2-background);color:var(--swal2-color);font-family:inherit;font-size:1rem}div:where(.swal2-container) div:where(.swal2-popup):focus{outline:none}div:where(.swal2-container) div:where(.swal2-popup).swal2-loading{overflow-y:hidden}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable{cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable div:where(.swal2-icon){cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging{cursor:grabbing}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging div:where(.swal2-icon){cursor:grabbing}div:where(.swal2-container) h2:where(.swal2-title){position:relative;max-width:100%;margin:0;padding:var(--swal2-title-padding);color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;word-wrap:break-word;cursor:initial}div:where(.swal2-container) div:where(.swal2-actions){display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:center;width:auto;margin:1.25em auto 0;padding:0}div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled[disabled]{opacity:.4}div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled:hover{background-image:linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1))}div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled:active{background-image:linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2))}div:where(.swal2-container) div:where(.swal2-loader){display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 rgba(0,0,0,0) #2778c4 rgba(0,0,0,0)}div:where(.swal2-container) button:where(.swal2-styled){margin:.3125em;padding:.625em 1.1em;transition:box-shadow .1s;box-shadow:0 0 0 3px rgba(0,0,0,0);font-weight:500}div:where(.swal2-container) button:where(.swal2-styled):not([disabled]){cursor:pointer}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm){border:0;border-radius:.25em;background:initial;background-color:#7066e0;color:#fff;font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):focus-visible{box-shadow:0 0 0 3px rgba(112,102,224,.5)}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny){border:0;border-radius:.25em;background:initial;background-color:#dc3741;color:#fff;font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):focus-visible{box-shadow:0 0 0 3px rgba(220,55,65,.5)}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel){border:0;border-radius:.25em;background:initial;background-color:#6e7881;color:#fff;font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):focus-visible{box-shadow:0 0 0 3px rgba(110,120,129,.5)}div:where(.swal2-container) button:where(.swal2-styled).swal2-default-outline:focus-visible{box-shadow:0 0 0 3px rgba(100,150,200,.5)}div:where(.swal2-container) button:where(.swal2-styled):focus-visible{outline:none}div:where(.swal2-container) button:where(.swal2-styled)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-footer){margin:1em 0 0;padding:1em 1em 0;border-top:1px solid var(--swal2-footer-border-color);color:inherit;font-size:1em;text-align:center;cursor:initial}div:where(.swal2-container) .swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto !important;overflow:hidden;border-bottom-right-radius:var(--swal2-border-radius);border-bottom-left-radius:var(--swal2-border-radius)}div:where(.swal2-container) div:where(.swal2-timer-progress-bar){width:100%;height:.25em;background:rgba(0,0,0,.2)}div:where(.swal2-container) img:where(.swal2-image){max-width:100%;margin:2em auto 1em;cursor:initial}div:where(.swal2-container) button:where(.swal2-close){position:var(--swal2-close-button-position);inset:var(--swal2-close-button-inset);z-index:2;align-items:center;justify-content:center;width:1.2em;height:1.2em;margin-top:0;margin-right:0;margin-bottom:-1.2em;padding:0;overflow:hidden;transition:var(--swal2-close-button-transition);border:none;border-radius:var(--swal2-border-radius);outline:var(--swal2-close-button-outline);background:rgba(0,0,0,0);color:var(--swal2-close-button-color);font-family:monospace;font-size:var(--swal2-close-button-font-size);cursor:pointer;justify-self:end}div:where(.swal2-container) button:where(.swal2-close):hover{transform:var(--swal2-close-button-hover-transform);background:rgba(0,0,0,0);color:#f27474}div:where(.swal2-container) button:where(.swal2-close):focus-visible{outline:none;box-shadow:inset 0 0 0 3px rgba(100,150,200,.5)}div:where(.swal2-container) button:where(.swal2-close)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-html-container){z-index:1;justify-content:center;margin:0;padding:var(--swal2-html-container-padding);overflow:auto;color:inherit;font-size:1.125em;font-weight:normal;line-height:normal;text-align:center;word-wrap:break-word;word-break:break-word;cursor:initial}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea),div:where(.swal2-container) select:where(.swal2-select),div:where(.swal2-container) div:where(.swal2-radio),div:where(.swal2-container) label:where(.swal2-checkbox){margin:1em 2em 3px}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea){box-sizing:border-box;width:auto;transition:border-color .1s,box-shadow .1s;border:1px solid #d9d9d9;border-radius:.1875em;background:var(--swal2-input-background);box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px rgba(0,0,0,0);color:inherit;font-size:1.125em}div:where(.swal2-container) input:where(.swal2-input).swal2-inputerror,div:where(.swal2-container) input:where(.swal2-file).swal2-inputerror,div:where(.swal2-container) textarea:where(.swal2-textarea).swal2-inputerror{border-color:#f27474 !important;box-shadow:0 0 2px #f27474 !important}div:where(.swal2-container) input:where(.swal2-input):focus,div:where(.swal2-container) input:where(.swal2-file):focus,div:where(.swal2-container) textarea:where(.swal2-textarea):focus{border:1px solid #b4dbed;outline:none;box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px rgba(100,150,200,.5)}div:where(.swal2-container) input:where(.swal2-input)::placeholder,div:where(.swal2-container) input:where(.swal2-file)::placeholder,div:where(.swal2-container) textarea:where(.swal2-textarea)::placeholder{color:#ccc}div:where(.swal2-container) .swal2-range{margin:1em 2em 3px;background:var(--swal2-background)}div:where(.swal2-container) .swal2-range input{width:80%}div:where(.swal2-container) .swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}div:where(.swal2-container) .swal2-range input,div:where(.swal2-container) .swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}div:where(.swal2-container) .swal2-input{height:2.625em;padding:0 .75em}div:where(.swal2-container) .swal2-file{width:75%;margin-right:auto;margin-left:auto;background:var(--swal2-input-background);font-size:1.125em}div:where(.swal2-container) .swal2-textarea{height:6.75em;padding:.75em}div:where(.swal2-container) .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:var(--swal2-input-background);color:inherit;font-size:1.125em}div:where(.swal2-container) .swal2-radio,div:where(.swal2-container) .swal2-checkbox{align-items:center;justify-content:center;background:var(--swal2-background);color:inherit}div:where(.swal2-container) .swal2-radio label,div:where(.swal2-container) .swal2-checkbox label{margin:0 .6em;font-size:1.125em}div:where(.swal2-container) .swal2-radio input,div:where(.swal2-container) .swal2-checkbox input{flex-shrink:0;margin:0 .4em}div:where(.swal2-container) label:where(.swal2-input-label){display:flex;justify-content:center;margin:1em auto 0}div:where(.swal2-container) div:where(.swal2-validation-message){align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:var(--swal2-validation-message-background);color:var(--swal2-validation-message-color);font-size:1em;font-weight:300}div:where(.swal2-container) div:where(.swal2-validation-message)::before{content:"!";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}div:where(.swal2-container) .swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:rgba(0,0,0,0);font-weight:600}div:where(.swal2-container) .swal2-progress-steps li{display:inline-block;position:relative}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:var(--swal2-progress-step-background);color:#fff}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:var(--swal2-progress-step-background)}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}div:where(.swal2-icon){position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;border:.25em solid rgba(0,0,0,0);border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;user-select:none}div:where(.swal2-icon) .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}div:where(.swal2-icon).swal2-error{border-color:#f27474;color:#f27474}div:where(.swal2-icon).swal2-error .swal2-x-mark{position:relative;flex-grow:1}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}div:where(.swal2-icon).swal2-warning{border-color:#f8bb86;color:#f8bb86}div:where(.swal2-icon).swal2-warning.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-warning.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .5s}div:where(.swal2-icon).swal2-info{border-color:#3fc3ee;color:#3fc3ee}div:where(.swal2-icon).swal2-info.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-info.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .8s}div:where(.swal2-icon).swal2-question{border-color:#87adbd;color:#87adbd}div:where(.swal2-icon).swal2-question.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-question.swal2-icon-show .swal2-icon-content{animation:swal2-animate-question-mark .8s}div:where(.swal2-icon).swal2-success{border-color:#a5dc86;color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;border-radius:50%}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}div:where(.swal2-icon).swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-0.25em;left:-0.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}div:where(.swal2-icon).swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}[class^=swal2]{-webkit-tap-highlight-color:rgba(0,0,0,0)}.swal2-show{animation:var(--swal2-show-animation)}.swal2-hide{animation:var(--swal2-hide-animation)}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{margin-right:initial;margin-left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}.swal2-toast{box-sizing:border-box;grid-column:1/4 !important;grid-row:1/4 !important;grid-template-columns:min-content auto min-content;padding:1em;overflow-y:hidden;background:var(--swal2-background);box-shadow:0 0 1px rgba(0,0,0,.075),0 1px 2px rgba(0,0,0,.075),1px 2px 4px rgba(0,0,0,.075),1px 3px 8px rgba(0,0,0,.075),2px 4px 16px rgba(0,0,0,.075);pointer-events:all}.swal2-toast>*{grid-column:2}.swal2-toast h2:where(.swal2-title){margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-toast .swal2-loading{justify-content:center}.swal2-toast input:where(.swal2-input){height:2em;margin:.5em;font-size:1em}.swal2-toast .swal2-validation-message{font-size:1em}.swal2-toast div:where(.swal2-footer){margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-toast button:where(.swal2-close){grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-toast div:where(.swal2-html-container){margin:.5em 1em;padding:0;overflow:initial;font-size:1em;text-align:initial}.swal2-toast div:where(.swal2-html-container):empty{padding:0}.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-toast .swal2-icon{grid-column:1;grid-row:1/99;align-self:center;width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:bold}.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-toast div:where(.swal2-actions){justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-toast button:where(.swal2-styled){margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;border-radius:50%}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.8em;left:-0.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}.swal2-toast.swal2-show{animation:swal2-toast-show .5s}.swal2-toast.swal2-hide{animation:swal2-toast-hide .1s forwards}@keyframes swal2-show{0%{transform:scale(0.7)}45%{transform:scale(1.05)}80%{transform:scale(0.95)}100%{transform:scale(1)}}@keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(0.5);opacity:0}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-0.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(0.4);opacity:0}50%{margin-top:1.625em;transform:scale(0.4);opacity:0}80%{margin-top:-0.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);opacity:1}}@keyframes swal2-rotate-loading{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}25%{transform:rotateZ(-25deg);opacity:.4}50%{transform:rotateZ(15deg);opacity:.8}75%{transform:rotateZ(-5deg);opacity:1}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-toast-show{0%{transform:translateY(-0.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(0.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0deg)}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-0.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}');var de=document.createElement("div"),We=document.getElementById("game-wrapper");document.getElementById("origin-menu")?.remove();document.getElementById("origin-toggler")?.remove();de.id="origin-menu";de.style="position: fixed;top: -10%;left: 10%;right: 10%;width: 80%;height: 80%;z-index: 2;background-color: rgba(0, 0, 0, 0.5);backdrop-filter: blur(5px);";We?.prepend(de);var ue=document.createElement("button");ue.id="origin-toggler";var ht=!1;We?.prepend(ue);ue.onclick=()=>{ht=!ht,ht?(ue.innerText="▼",de.style.top="-100vh"):(ue.innerText="▲",de.style.top="10%")};ue.onclick({});var pe=document.createElement("DIV");pe.classList.add("menu-left");de.append(pe);var Bn=!0;function q(e){let t=document.createElement("div");Bn==!1?(t.append(document.createElement("br")),t.append(document.createElement("br"))):Bn=!1,t.classList.add("menu-area"),t.style.textAlign="center",pe.append(t);let n=document.createElement("h1");return n.innerText=e,n.style.textAlign="center",n.style.color="white",t.append(n),t}var Ye=document.createElement("h1");Ye.classList.add("menu-title");Ye.innerText="Play Origin";Ye.style.textAlign="center";pe.append(Ye);var Ve=document.createElement("h2");Ve.style.fontSize="25px";Ve.style.color="white";Ve.innerHTML="
      Press SHIFT to show/hide the menu. Scroll down in the menu for more mods.";pe.append(Ve);var Ue=document.createElement("h3");Ue.style.fontSize="20px";Ue.innerHTML=`

      -`;Ue.style.color="white";me.append(Ue);var u={player:q("Player Mods"),inventory:q("Inventory Mods"),location:q("Location Mods"),pets:q("Pet Mods"),battle:q("Battle Mods"),battlepass:q("Battle Pass Mods"),minigames:q("Minigame Mods"),misc:q("Miscellaneous Mods"),utility:q("Utility Mods"),beta:q("Beta Testing | Beta Mods may damage your account")};localStorage.hasTip?console.log("Player already has tip."):((async()=>await ee.fire({title:"Welcome!",html:"To get started with the hacks, click this dropdown!",icon:"info"}))(),localStorage.hasTip=!0,console.log("Player was shown the tip."));localStorage.getItem("level")&&(c.player.getLevel=()=>localStorage.getItem("level"),console.log("Loaded menu from localStorage."));window.__ORIGIN_ABORT__?.abort();var $n=new AbortController;window.__ORIGIN_ABORT__=$n;var yt=!0;document.addEventListener("keydown",function(e){e.key=="Shift"&&(e.stopImmediatePropagation(),console.log("Shift key was pressed."),yt==!0?(console.log("Hiding mod menu..."),document.getElementById("origin-menu").style.display="none",document.getElementById("origin-toggler").style.display="none",yt=!1,console.log("Hidden mod menu.")):(console.log("Showing mod menu..."),document.getElementById("origin-menu").style.display="block",document.getElementById("origin-toggler").style.display="block",yt=!0,console.log("Shown mod menu.")))},{capture:!0,signal:$n.signal});Ln();var p=class{constructor(t,n,o){this.parent=t;this.name="",this.description="",this.element=document.createElement("button"),this.element.classList.add("menu-hack"),this.parent.append(this.element),n&&this.setName(n),o&&this.setDesc(o)}parent;element;name;description;setName(t){return this.element.innerText=t,this.name=t,this}setClick(t){return this.element.onclick=async()=>{await t(),$(),console.log(`Triggered ${this.name}.`)},this}setDesc(t){return this.element.title=t,this.description=t,this}};var k=class extends p{constructor(n,o,s){super(n,o,s);this.parent=n;this.element.setAttribute("status","false"),this.migrateOldKey(),this.setClick(async()=>{this.status=!this.status,this.status?(localStorage.setItem(this.getStorageKey(),"true"),await this.enabled?.()):(localStorage.setItem(this.getStorageKey(),"false"),await this.disabled?.())})}parent;enabled;disabled;migrateOldKey(){let n=this.getStorageKey();this.name!==n&&localStorage.getItem(this.name)!==null&&(localStorage.setItem(n,localStorage.getItem(this.name)),localStorage.removeItem(this.name))}getStorageKey(){let n=this.parent.querySelector("h1")?.innerText??"";return n?`${n}::${this.name}`:this.name}get status(){return JSON.parse(this.element.getAttribute("status"))}set status(n){this.element.setAttribute("status",n.toString())}setEnabled(n){if(this.enabled=n,localStorage.getItem(this.getStorageKey())==="true")try{this.element.click()}catch(o){console.warn(`[Origin] Failed to restore toggle state for "${this.name}":`,o)}return this}setDisabled(n){return this.disabled=n,this}};function F(e,t){let n=c.constants;return!n||typeof n.set!="function"?!1:(n.set(e,t),!0)}new k(u.battle,"Instant Kill [PvE]","Makes your spells do insane damage in PvE!").setEnabled(async()=>(r.modifiers.damage=P,l.fire("Enabled!","You will now do insane damage in PvE!","success"))).setDisabled(()=>(r.modifiers.damage=1,l.fire("Disabled!","You will no longer do insane damage in PvE!","success")));new p(u.battle,"PvP Health [PvP]","Increases your HP in PvP by a hell ton.").setClick(async()=>(r.pvpHP=P,r.getMaxHearts=()=>P,l.fire("Success!","You now have lots of health!","success")));new p(u.battle,"Set Battle Hearts [PvP, PvE]","Sets your hearts in battle, automatically raise your max hearts in PvP or PvE.").setClick(async()=>{let e=await b.fire("Health Amount","How much HP do you want?","question");if(e.value!==void 0)return r.getMaxHearts=()=>+e.value,r.pvpHP=+e.value,r.data.hp=+e.value,l.fire("Success!","Your hearts have been set.","success")});new p(u.battle,"Fill Battle Energy [PvP, PvE]","Fills up your battle energy, if you are in PvP or PvE.").setClick(async()=>{let e=Ae.state.getCurrentState();return"teams"in e?(e.teams[0].setEnergy(99),l.fire("Success!","Your battle energy has been filled.","success")):l.fire("Error","You are currently not in a battle.","error")});new k(u.battle,"Disable math [PvP, PvE]","Disable math in PvP, PvE, anywhere! This doesn't work in the Floatling town.").setEnabled(async()=>F("GameConstants.Debug.EDUCATION_ENABLED",!1)?l.fire("Enabled!","You will no longer do Math!","success"):l.fire("Error","FlagProvider service not found.","error")).setDisabled(async()=>(F("GameConstants.Debug.EDUCATION_ENABLED",!0),l.fire("Disabled!","You will now do Math!","success")));new k(u.battle,"Skip enemy turn").setEnabled(async()=>F("GameConstants.Battle.SKIP_ENEMY_TURN",!0)?l.fire("Skipping!","Enemy turns will now be skipped.","success"):l.fire("Error","FlagProvider service not found.","error")).setDisabled(async()=>(F("GameConstants.Battle.SKIP_ENEMY_TURN",!1),l.fire("Disabled","Enemy turns will no longer be skipped.","success")));new p(u.battle,"Escape Battle [PvP, PvE]","Escape any battle, PvP or PvE!").setClick(async()=>{let e=Ae.state.current;if(e==="PVP")return Object.fromEntries(c.instance.game.state.states).PVP.endPVP(),l.fire("Escaped!","You have successfully escaped from the PvP battle.","success");if(e==="CoOp")return c.instance.prodigy.world.$(r.data.zone),l.fire("Escaped!","You have successfully escaped from the battle.","success");if(e==="SecureBattleRevamp"){let t=c.instance?._game?._state?._current?._battleController;return!t||typeof t.attemptEscape!="function"?l.fire("Error","BattleController not available on current state.","error"):(await t.attemptEscape(),l.fire("Escaped!","You have successfully escaped from the PvE battle.","success"))}return["Battle","SecureBattle"].includes(e)?(Object.fromEntries(c.instance.game.state.states)[e].runAwayCallback(),l.fire("Escaped!","You have successfully escaped from the PvE battle.","success")):l.fire("Invalid State.","You are currently not in a battle.","error")});new p(u.battle,"Win Battle [PvE]","Instantly win the current PvE battle.").setClick(async()=>{if(Ae.state.current!=="SecureBattleRevamp")return l.fire("Invalid State.","You are currently not in a PvE battle.","error");let e=c.instance?.game?._state?._current?._battleController;return!e||typeof e.onVictory!="function"?l.fire("Error","BattleController not available on current state.","error"):(await e.onVictory(),l.fire("Victory!","You won the battle!","success"))});function Bs(){let e=c?.prodigy??c?.instance?.prodigy;return e?._currentBattlePass??e?._battlePass??null}function bt(e){let t=Bs();if(!t||typeof t!="object")return g.fire("Error","Battle Pass not found.","error");let n=t._tiers;return!n||typeof n!="object"?g.fire("Error","Tiers not found in battle pass.","error"):(Object.values(n).forEach(o=>{o&&(o.isCompleted=!0,o[e]&&(o[e].claimed=!1,o[e].claimable=!0))}),l.fire("Success!","Rewards unlocked.","success"))}new p(u.battlepass,"Treasure Free","Unlocks all free Battle Pass tier rewards.").setClick(async()=>bt("freeReward"));new p(u.battlepass,"Treasure Core","Unlocks all Core (bottom premium) Battle Pass tier rewards.").setClick(async()=>bt("bottomPremiumReward"));new p(u.battlepass,"Treasure Plus","Unlocks all Plus (top premium) Battle Pass tier rewards.").setClick(async()=>bt("topPremiumReward"));var W=["Boots","Buddies","Fossils","Hats","Items","Key Items","Tower Town Frames","Tower Town Interiors","Mounts","Outfits","Relics","Weapons","Currencies"],C=["boots","follow","fossil","hat","item","key","mathTownFrame","mathTownInterior","mount","outfit","spellRelic","weapon","currency"],Y=(e,t)=>e.map(n=>({ID:n.ID,N:t})).filter(n=>n!==void 0),On=(e,t)=>e.map(n=>({ID:n.ID,quantity:t})).filter(n=>n!==void 0);function Hn(e){if(c.player.userID!==e){let n=c.instance.prodigy.friendsListNetworkHandler.friendsList.length,o=c.instance.prodigy.friendsListNetworkHandler.classList.length;c.instance.prodigy.gameContainer.get("2e1-e659").create("house-visit","click","hub",n,o,null,null,e).broadcast()}let t=c.instance.prodigy.world.getZone(c.instance.prodigy.world.getCurrentZone());return t?t.handleLeaving(2,()=>Ls(e)):g.fire({title:"Error",text:"You are not in a zone!",icon:"error"})}function Ls(e){c.instance.prodigy.loading(!0);let t=n=>{let o=n!=null?n[e]:null;if(o!==null&&o.house!==void 0&&o.house!==null){c.instance.prodigy.loading(!1);let s=c.cloneDeep(c.player.house);return s.setItems(o.house),o.data.allowsHouseVisitors!==void 0&&o.data.allowsHouseVisitors!==null&&o.data.allowsHouseVisitors?c.instance.prodigy.world._("house",null,null,{house:s,getAllowsHouseVisitors:()=>o.data.allowsHouseVisitors!==void 0&&o.data.allowsHouseVisitors!==null?o.data.allowsHouseVisitors:!1,setAllowsHouseVisitors:a=>{o.data.allowsHouseVisitors=a}}):g.fire(`Teleporting to ${e} is not allowed.`,"Try another user.","error")}};return c.network.getCharData(e.toString(),["house","data"],t,t),l.fire("Teleported to house","You have been teleported to the house!","success")}var Ge=async e=>(await g.fire({input:"select",inputOptions:new Map(c.player.kennel.data.map((n,o)=>[o.toString(),`Level ${n.level} - ${n.nickname??c.gameData.pet.find(s=>+s.ID==+n.ID)?.data.name??"Unknown"}`])),title:"Choose Pet",text:e})).value,Ee=[125,126,127,128,129,134,135,136,137];function fe(){c.gameData.pet.forEach(e=>{r.kennel.addPet(e.ID,P,26376,100)}),r.kennel._encounterInfo._data.pets=[],c.gameData.pet.map(e=>{r.kennel._encounterInfo._data.pets.push({firstSeenDate:Date.now(),ID:e.ID,timesBattled:1,timesRescued:1})}),r.kennel.petTeam.forEach(e=>{e&&e.assignRandomSpells&&e.assignRandomSpells()})}function we(e){C.forEach(t=>{r.backpack.data[t]=Y(c.gameData[t].filter(n=>t==="follow"?!Ee.includes(n.ID):n),e)}),c.gameData.dorm.forEach(t=>r.house.data.items[t.ID]={A:[],N:e})}function ge(){let e=()=>r.backpack.data.item.findIndex(t=>t.ID===84||t.ID===85||t.ID===86);for(;e()>-1;)r.backpack.data.item.splice(e(),1)}var _n=!1;function vt(e){_n=e}(async()=>setInterval(async()=>{_n&&c.instance.prodigy.open.menuCloseAll()},200))();new p(u.beta,"Edit Pet [BETA]","Edit a pet.").setClick(async()=>{if(!(await E.fire({title:"Hang on!",html:"This hack may damage your account with various bugs, for example you may be unable to do Rune Run.

      Proceed?",icon:"warning"})).value)return console.log("Cancelled.");let e=await Ge("Choose the pet to edit.");if(e===void 0)return;let t=r.kennel.data[e],n=await g.fire({input:"select",inputOptions:{level:"Level",attacks:"Attacks",name:"Name"},title:"Edit Property",text:"What do you want to edit?"});if(n.value!==void 0){if(n.value==="level"){let o=await b.fire("Level Number","What level do you want to set your pet to?","question");return o.value===void 0?void 0:(t.level=+o.value,l.fire("Success!","The pet's level has been set.","success"))}else if(n.value==="attacks"){let o=c.gameData.spell,s=document.createElement("div"),a=document.createElement("select");a.classList.add("selectSpell");for(let m of o){let f=document.createElement("option");f.value=m.ID.toString(),f.innerText=`${m.ID}: ${m.name} (${m.data.element}) - Damage: ${m.data.damage}`,a.options.add(f)}s.append(a),s.append(a.cloneNode(!0));let d=await g.fire({title:"Attack List",focusConfirm:!1,showCancelButton:!0,html:s,preConfirm:()=>Array.prototype.slice.call(document.querySelectorAll(".selectSpell")).map(m=>m.options[m.selectedIndex].value)});return d.value===void 0?void 0:(t.foreignSpells.splice(0,2,...d.value.map(m=>+m)),l.fire("Attacks updated!","The attack list of the pet you selected has been edited.","success"))}else if(n.value==="name"){let o=await K.fire("Input Name","What do you want to name the pet?","question");return o.value===void 0?void 0:(t.nickname=o.value,l.fire("Successfully renamed!","The name of the pet has been changed.","success"))}}});new k(u.beta,"(client side) Toggle Invisibility [BETA]","Lets you appear invisible on your own screen.").setEnabled(async()=>{he.user.visible=!1}).setDisabled(async()=>{he.user.visible=!0});new k(u.beta,"Toggle Close Popups [BETA]","Automatically closes popups in Prodigy.").setEnabled(async()=>(vt(!0),l.fire("Enabled","Toggle Close Popups is now enabled.","success"))).setDisabled(async()=>(vt(!1),l.fire("Enabled","Toggle Close Popups is now disabled.","success")));new p(u.beta,"Hypermax Account [BETA]").setClick(async()=>{if(!(await E.fire({title:"Hang on!",html:"This hack will damage your account with various bugs, for example you may be unable to do Rune Run/Arena, amd you will recieve 418s and inavtivity kicks.

      Proceed?",icon:"warning"})).value)return;r.data.gold=99e5,console.log("Set player gold to 9900000.");let t=100-2,n=1.042;r.data.stars=Math.round((1-Math.pow(n,t))/(1-n)*20+10),r.data.level=100,r.getLevel=()=>r.data.level,console.log("Set player level to 100"),r.data.bountyScore=100,console.log("Set player's bounty points to 100.");for(let f=0;f<99;f++)V.giftBoxController.receiveGiftBox(null,Ie("giftBox",1));console.log("Obtained 100 conjure cubes."),r.data.win=P,console.log("Set player's wins to VERY_LARGE_NUMBER"),r.data.loss=0,console.log("Set player's losses to 0."),r.modifiers.damage=P,console.log("Enabled damage multiplier."),r.pvpHP=P,r.getMaxHearts=()=>P,console.log("PvP health obtained.");for(var o=0;o<100;o++)r.achievements.data.progress[o]=10;console.log("Obtained all achievements."),r.data.tower=100,console.log("Set tower floor to 100."),r.getMaxHearts=()=>P,r.pvpHP=P,r.data.hp=P,console.log("Maxed out PvE health."),we(99e4),ge(),l.fire("Success!","All items added!","success"),console.log("All items added!"),r.backpack.data.mount=Y(c.gameData.mount,1),console.log("Added all mounts."),fe(),console.log("Added all pets."),c.gameData.pet.filter(f=>[158,166,168].includes(f.ID)).forEach(f=>{r.kennel.addPet(f.ID,P,26376,100)}),r.kennel.petTeam.forEach(f=>{f&&f.assignRandomSpells&&f.assignRandomSpells()}),console.log("Added Mythical Epics."),c.gameData.pet.filter(f=>[125,126,127,128,129,130,131,132,133].includes(f.ID)).forEach(f=>{r.kennel.addPet(f.ID,P,26376,100)}),r.kennel.petTeam.forEach(f=>{f&&f.assignRandomSpells&&f.assignRandomSpells()}),console.log("Added Legacy Epics."),c.constants.constants["GameConstants.Inactivity.LOG_OUT_TIMER_SECONDS"]=0,console.log("Inactivity Kick Disabled."),r._playerContainer.walkSpeed=20,console.log("Player walkspeed set to 20.");let d=100,m;return Array.from(c.instance.prodigy.gameContainer._inversifyContainer._bindingDictionary._map).forEach(f=>{try{c.instance.prodigy.gameContainer.get(f[0]).battleData&&(m=f[0])}catch{console.log(`Error for ${f[0]}`)}}),c.instance.prodigy.gameContainer.get(m).battleData._secureCharacterState._data.inventory.orb=On(c.gameData.orb,d),r.equipment.setHat(200),r.equipment.setBoots(93),r.equipment.setOutfit(161),r.equipment.setWeapon(196),$(),console.log("Character Saved."),r.appearanceChanged=!0,console.log("Appearance Refreshed."),c.instance.prodigy.open.menuCloseAll(),console.log("Popups closed."),$(),console.log("Character Saved."),console.log("Max Account Successful."),l.fire("Maxed!","Check your backpack!","success")});new p(u.inventory,"Item stacker").setClick(async()=>{let e=await b.fire("Amount","How many of every item would you like?","question");if(e.value&&(await E.fire("Are you sure you want to get all items in the game?")).value)return we(e.value),ge(),l.fire("Success!","All items added!","success")});new p(u.inventory,"Clear inventory").setClick(async()=>{(await E.fire("Are you sure you want to clear your inventory?")).value&&(Object.keys(r.backpack.data).forEach(e=>r.backpack.data[e]=[]),l.fire("Success!","Inventory cleared.","success"))});new p(u.inventory,"Selector (Basic)").setClick(async()=>{let e=await g.fire({title:"What would you like to obtain?",input:"select",inputOptions:W,inputPlaceholder:"Select...",inputValidator:t=>t?"":"Please select which you'd like to obtain.",showCancelButton:!0}).then(async t=>{let n=parseInt(t.value),o=W[n],s=C[n];if(!o)return;let a=await b.fire("Amount","How many each object would you like?","question");a.value&&(await E.fire(`Are you sure you want to get all ${o.toLowerCase()}?`)).value&&(r.backpack.data[s]=Y(c.gameData[s].filter(d=>s==="follow"?!Ee.includes(d.ID):d),a.value),l.fire(`${o} Added!`,`All ${o.toLowerCase()} have been added to your inventory!`,"success"),$())})});new p(u.inventory,"Selector (Advanced)","Choose a specific object and quantity to obtain.").setClick(async()=>{let e=await g.fire({title:"What would you like to obtain?",input:"select",inputOptions:W,inputPlaceholder:"Select...",inputValidator:t=>t?"":"Please select which you'd like to obtain.",showCancelButton:!0}).then(async t=>{if(!c.gameData[C[t.value]])return;let n=[];c.gameData[C[t.value]].forEach(s=>{n.push(s.data.name)});let o=await g.fire({title:`What specific object categorized as ${W[t.value].toLowerCase()} would you like to get?`,input:"select",inputOptions:n,inputPlaceholder:"Select...",inputValidator:s=>s?"":"Please select which you'd like to get.",showCancelButton:!0}).then(async s=>{let a=parseInt(s.value);if(!c.gameData[C[t.value]][a])return;let d=await b.fire("Amount","How many of the object would you like?","question");if(!d.value)return;let m=r.backpack.data[C[t.value]].findIndex(f=>f.ID===c.gameData[C[t.value]][a].ID);return m===-1?r.backpack.data[C[t.value]].push({ID:c.gameData[C[t.value]][a].ID,N:d.value}):r.backpack.data[C[t.value]][m].N=d.value,console.log(c.gameData[C[t.value]][a].ID),$(),l.fire(`${W[t.value]} Added!`,`Your selected ${W[t.value].toLowerCase()} have been added.`,"success")})})});new p(u.inventory,"Obtain All Furniture").setClick(async()=>{let e=await b.fire("Amount","How many of each piece of furniture would you like?","question");if(e.value&&(await E.fire("Are you sure you want to get all furniture?")).value)return c.gameData.dorm.forEach(t=>r.house.data.items[t.ID]={A:[],N:e.value}),l.fire("Furniture Added!","All furniture has been added to your inventory!","success")});new p(u.inventory,"Obtain All Mounts","This gives you all of the mounts in the game.").setClick(async()=>(r.backpack.data.mount=Y(c.gameData.mount,1),l.fire("Mounts Added!","All mounts have been added to your inventory!")));new p(u.inventory,"Remove item").setClick(async()=>{let e=await g.fire({title:"What category would you like to remove an item from?",input:"select",inputOptions:W,inputPlaceholder:"Select...",inputValidator:a=>a?"":"Please select which you'd like to obtain.",showCancelButton:!0});if(!c.gameData[C[e.value]])return;let t=c.gameData[C[e.value]].map(a=>a.data.name),n=await g.fire({title:`What specific object categorized as ${W[e.value].toLowerCase()} would you like to remove?`,input:"select",inputOptions:t,inputPlaceholder:"Select...",inputValidator:a=>a?"":"Please select which you'd like to get.",showCancelButton:!0});if(n=parseInt(n.value),!c.gameData[C[e.value]][n])return;let o=await b.fire("Amount","How many of the object would you like to remove?","question");if(!o.value)return;if(r.backpack.data[C[e.value]].findIndex(a=>a.ID===c.gameData[C[e.value]][n].ID)===-1){await g.fire("Item Does Not Exist",`You do not have any ${c.gameData[C[e.value]][n].name}.`,"error");return}let s=r.backpack.data[C[e.value]].findIndex(a=>a.ID===c.gameData[C[e.value]][n].ID);return r.backpack.data[C[e.value]][s].N-=parseInt(o.value),r.backpack.data[C[e.value]][s].N<=0&&r.backpack.data[C[e.value]].splice(s,1),$(),l.fire("Removed!",`Successfully removed ${o.value} ${c.gameData[C[e.value]][n].name}!`,"success")});new p(u.inventory,"Get All Gems","Adds one of each gem type to your backpack and saves.").setClick(async()=>([3,4,10,11,17].forEach(t=>{let n=r.backpack.data.key.find(o=>o.ID===t);n?n.N+=1:r.backpack.data.key.push({ID:t,N:1})}),r.appearance.updated=!0,r.updated=!0,r.saveEnabled=!0,typeof r.forceSaveCharacter=="function"&&r.forceSaveCharacter(),r.appearanceChanged=!0,r.backpack.updated=!0,l.fire("Done!","All gems added to your backpack.","success")));var Ke=!0;new k(u.location,"WASD Movement","Allows you to walk through walls or on air with WASD movement in Prodigy.").setEnabled(async()=>(Ke=!0,l.fire("Enabled!","WASD Movement is now enabled.","success"))).setDisabled(async()=>(Ke=!1,l.fire("Disabled!","WASD Movement is now disabled.","success"))).status=!0;new p(u.location,"Edit walkspeed","Lets you set your walkspeed.").setClick(async()=>{let e=await K.fire("What do you want to set your walk speed to?");if(e.value){if(r._playerContainer)r._playerContainer.walkSpeed=parseFloat(e.value)||1.5;else{let t=setInterval(()=>{r._playerContainer&&(clearInterval(t),r._playerContainer.walkSpeed=parseFloat(e.value))},100)}return l.fire("Success!",`Successfully made walk speed ${parseFloat(e.value)||1.5}!`,"success")}});var Nn=-1;new k(u.location,"Toggle Click Teleporting").setEnabled(async()=>(Nn=setInterval(()=>{try{r._playerContainer.walkSpeed=500}catch{}},16),l.fire("Success!","Successfully enabled teleport click.","success"))).setDisabled(async()=>(clearInterval(Nn),r._playerContainer.walkSpeed=1.5,l.fire("Success!","Successfully disabled teleport click.","success")));new p(u.location,"Teleport To Map (interactive)").setClick(async()=>{let e=g.mixin({focusConfirm:!1,showCancelButton:!0,preConfirm:()=>document.querySelector(".radioDiv[checked]")?.getAttribute("zone")}),t=document.createElement("div");t.classList.add("radioContainer");for(let m of Object.keys(V.world.zones)){let f=document.createElement("DIV");f.classList.add("radioDiv"),f.setAttribute("zone",m);let I=Et[m];I?f.style.backgroundImage=`url(${I})`:f.innerText=m,f.onclick=()=>{document.querySelectorAll(".radioDiv[checked]").forEach(X=>X.removeAttribute("checked")),f.setAttribute("checked","")},t.append(f)}let n=await e.fire({title:"Teleport Zone",html:t,customClass:{popup:"radioSwal"}});if(!n.value)return;let o=Object.keys(V.world.zones[n.value].maps),s=await g.fire({input:"select",inputOptions:new Map(o.map(m=>[m,m])),title:"Map",text:"Which map in the zone do you want to teleport to?"});if(!s.value)return;let a=(await b.fire("Please enter the x to teleport to. (Try 500?)")).value||500,d=(await b.fire("Please enter the y to teleport to. (Try 500?)")).value||500;return V.world.zones[n.value].teleport(s.value,a,d,{},{}),l.fire("Teleported","You have been teleported!","success")});new p(u.location,"Teleport to house by userID").setClick(async()=>{let e=(await b.fire("Please enter the userID.")).value;if(e)return Hn(e),l.fire("Teleported!","You have been teleported!","success")});new p(u.location,"Get Map Location").setClick(async()=>{let e=r.data.zone;navigator.clipboard.writeText(e).then(async function(){return console.log("Async: Copying to clipboard was successful!"),g.fire({title:"Map Location",html:`You are at
      ${e} .
      You can save this to get to the same zone.

      Your location is has also been copied to your clipboard.`,icon:"info"})},async function(t){return console.error("Async: Could not copy text: ",t),g.fire({title:"Map Location",html:`You are at
      ${e} .
      You can save this to get to the same zone.`,icon:"info"})})});new k(u.minigames,"69x Walk Speed [Dyno Dig]","Walk so fast that you're teleporting, in Dyno Dig.").setEnabled(async()=>(c.instance.game.state.states.get("DinoDig").walkSpeed=69,l.fire("Enabled!","You will now walk so fast that you're teleporting in Dyno Dig.","success"))).setDisabled(async()=>(c.instance.game.state.states.get("DinoDig").walkSpeed=1.5,l.fire("Disabled!","You will now walk at normal speed, in Dyno Dig.","success")));new p(u.minigames,"Dino Dig +100 Days","Adds 100 days to the active Dino Dig timer.").setClick(async()=>{let e=c.instance.game.state.states.get("DinoDig");return e?.timer?.addTime?(e.timer.addTime(864e7),l.fire("Done!","Added 100 days to the Dino Dig timer.","success")):g.fire("Error","You are not currently in Dino Dig.","error")});new p(u.minigames,"End Dino Dig","Instantly ends the current Dino Dig session.").setClick(async()=>{let e=c.instance.game.state.states.get("DinoDig");return e?.timer?.addTime?(e.timer.addTime(-9e15),l.fire("Done!","Dino Dig session ended.","success")):g.fire("Error","You are not currently in Dino Dig.","error")});var kt=document.createElement("button"),Se=null;function Rn(){Se||Ms()}function zn(){Se&&(clearInterval(Se),Se=null),document.getElementById("fps-counter")?.remove()}function Ms(){kt.id="fps-counter",We?.prepend(kt),Se=setInterval(()=>{kt.innerText=r.game.fps._framerate.toFixed(2)+" FPS"},300)}new p(u.misc,"Skip Tutorial").setClick(async()=>{let e=(t,n,o,s)=>{c.instance.prodigy.world.getZone(t).testQuest(n,o,s);try{Object.fromEntries(c.instance.game.state.states).TileScreen.process()}catch{}};e("house",2),e("academy",2),r.state.set("tutorial-0",4),r.backpack.addKeyItem(13,0),r.tutorial.data.menus[14]=[1],c.instance.prodigy.open.map(!0,[]),r.onTutorialComplete(),r.data.level=Math.max(r.data.level,5)});new k(u.beta,"FPS Counter [BETA]","Shows you a framerate counter").setEnabled(async()=>{Rn()}).setDisabled(async()=>{zn()});try{let e=null;new k(u.misc,"Unlimited Spins","Lets you spin the wheel as many times as you want!").setEnabled(async()=>(e=r.canSpin,r.canSpin=()=>!0,l.fire("Enabled!","You can now spin the wheel as many times as you want!","success"))).setDisabled(async()=>(r.canSpin=e,l.fire("Disabled!","You can now spin the wheel only when allowed.","success")))}catch(e){console.error("Unlimited Spins ERROR: "+e)}new p(u.misc,"Reset Account","Completely resets your account.").setClick(async()=>{if((await E.fire("Are you sure you want to reset your account?","This action is not reversible.")).value)return r.resetAccount(),g.fire("Reset!","Your account has been reset. Reload Prodigy for the full effect.","success")});new p(u.misc,"[Fix] Fix Battle Crash").setClick(async()=>(r.kennel.petTeam.forEach(e=>{e&&e.assignRandomSpells&&e.assignRandomSpells()}),l.fire("Success!","Fixed kennel attack bug!","success")));new p(u.misc,"[Fix] Stuck in Unfinished Tower Fix","Takes you out of an unfinished tower if you're stuck in one.").setClick(async()=>(c.instance.prodigy.world.zones.house.teleport("exit"),l.fire("Success!","You've been teleported outside of your house.","success")));new k(u.misc,"Disable Monster Encounters").setEnabled(async()=>F("GameConstants.Debug.SCALE_ENCOUNTER_DISTANCE",0)?l.fire("Enabled!","Monsters will no longer battle you.","success"):l.fire("Error","FlagProvider service not found.","error")).setDisabled(()=>(F("GameConstants.Debug.SCALE_ENCOUNTER_DISTANCE",1),l.fire("Disabled!","Monsters will now battle you.","success")));new p(u.misc,"Bobbified","Turns you into Bobby Fancywoman (level 69, specific appearance).").setClick(async()=>{if((await E.fire("Are you sure?","You will be transformed into Bobby Fancywoman.")).value)return r.name.data.firstName=44,r.name.data.middleName=754,r.name.data.lastName=882,r.data.stars=-1e22,r.data.level=69,r.appearance.setEyeColor(1),r.appearance.setFace(4),r.appearance.setHair(19,1),r.appearance.setSkinColor(1),r.equipment.setFollow(19),r.equipment.setHat(19),r.equipment.setBoots(19),r.equipment.setOutfit(19),r.equipment.setWeapon(19),l.fire("Done!","You are now Bobby Fancywoman.","success")});new p(u.pets,"Get All Pets").setClick(async()=>(await E.fire("Would you like to add all pets to your pets?")).value?(fe(),l.fire("Success!","All pets have been added!","success")):console.log("Cancelled"));new p(u.pets,"Get All Legacy Epics").setClick(async()=>(await E.fire({title:"This may damage your account.",html:"Attempting to add legacy epics may damage your account.

      Warning: this does NOT save on reload — the pets will disappear after refreshing.

      Would you still like to add all legacy epics to your team?",icon:"warning"})).value?(c.gameData.pet.filter(t=>[125,126,127,128,129,130,131,132,133].includes(t.ID)).forEach(t=>{r.kennel.addPet(t.ID,P,26376,100)}),r.kennel.petTeam.forEach(t=>{t&&t.assignRandomSpells&&t.assignRandomSpells()}),l.fire("Success!","All legacy epics have been added!","success")):console.log("Cancelled"));new p(u.pets,"Get All Mythical Epics").setClick(async()=>(await E.fire({title:"Add all mythical epics?",html:"Warning: this does NOT save on reload — the pets will disappear after refreshing.

      Would you like to add all mythical epics to your pets?",icon:"warning"})).value?(c.gameData.pet.filter(t=>[158,164,165,166,167,168,169,170,171,189].includes(t.ID)).forEach(t=>{r.kennel.addPet(t.ID,P,26376,100)}),r.kennel.petTeam.forEach(t=>{t&&t.assignRandomSpells&&t.assignRandomSpells()}),l.fire("Success!","All mythical epics have been added!","success")):console.log("Cancelled"));new p(u.pets,"Clear Pets").setClick(async()=>(await E.fire("Would you like to delete all of your pets?")).value?(r.kennel.data.length=0,l.fire("Success!","Your pets have been cleared!","success")):console.log("Cancelled"));new p(u.pets,"Add Pet","Adds a pet from a list.").setClick(async()=>{let e=await g.fire({input:"select",inputOptions:new Map(c.gameData.pet.map(t=>[t.ID.toString(),`${t.ID}: ${t.data.name}`])),title:"Choose Pet",text:"Which pet do you want to obtain?"});if(e.value!==void 0)return r.kennel.addPet(e.value),r.kennel._encounterInfo._data.pets.push({firstSeenDate:Date.now(),ID:e.value,timesBattled:1,timesRescued:1}),l.fire("Success!","Your chosen pet has been added to your pets!","success")});new p(u.pets,"Uncap pet level [Client Side]","Change your pet's level to anything, even over 100. This hack won't save when you reload Prodigy.").setClick(async()=>{let e=r.kennel.petTeam.slice(0);e.shift();let t=e.map(a=>a.getName()),n=await g.fire({title:"Which pet would you like to edit?",input:"select",inputOptions:t,inputPlaceholder:"Select...",inputValidator:a=>a?"":"Please select which you'd like to obtain.",showCancelButton:!0}),o=await b.fire("Level","What would you like to set your pet's level to? (Can be set over 100)","question");if(!o.value)return;let s=o.value;return r.kennel.petTeam[parseInt(n.value)+1].getLevel=()=>Number(s),l.fire("Updated!","The level of your pet was successfully updated. Note: this hack is client-side.","success")});new p(u.pets,"Delete Pet","Delete a pet.").setClick(async()=>{let e=await Ge("Which pet do you wish to delete?");if(e!==void 0)return r.kennel.data.splice(e,1),l.fire("Successfully deleted!","The selected pet was deleted successfully.","success")});new p(u.pets,"All Pets Level 150","Replaces all pets with every pet at level 150. WARNING: Erases current pet data.").setClick(async()=>{if((await E.fire("Are you sure?","This will erase all your current pet data and replace it with every pet at level 150.")).value)try{let e=(d,m)=>Math.floor(Math.random()*(m-d+1)+d),t=(d,m)=>{let f=m.data.statHealth,I=500/1.25*Math.pow(Math.pow(1.25,.25),f-1),X=100/1.25*Math.pow(Math.pow(1.25,.25),f-1);return Math.ceil(I+(d-1)*X)},s=(d=>{if(d===1)return 0;if(d===2)return 10;let m=d-2,f=1.042;return Math.round((1-Math.pow(f,m))/(1-f)*20+10)})(150),a=c.gameData.pet;return r.kennel.data.length=0,a.forEach(d=>{r.kennel.addPet(d.ID,t(150,d),s,150)}),r.kennel._encounterInfo._data.pets=a.map(d=>({firstSeenDate:Date.now()-e(2e4,12e4),ID:d.ID,timesBattled:1,timesRescued:1,rescueAttempts:1})),r.kennel.petTeam.forEach(d=>{d&&d.assignRandomSpells&&d.assignRandomSpells()}),g.fire("Done!","All pets added at level 150. Leave the game open for ~2 minutes to fully sync.","success")}catch(e){return g.fire("Error","Failed to add pets: "+e,"error")}});new p(u.player,"Max Account").setClick(async()=>{if(!(await E.fire("Are you sure that you want to max your account?","We recommend doing this on an alt.")).value)return console.log("Cancelled");r.data.gold=99e5,console.log("Set player gold to 9900000.");let t=100-2,n=1.042;r.data.stars=Math.round((1-Math.pow(n,t))/(1-n)*20+10),r.data.level=100,r.getLevel=()=>r.data.level,console.log("Set player level to 100"),r.data.bountyScore=100,console.log("Set player's bounty points to 100.");for(let d=0;d<99;d++)V.giftBoxController.receiveGiftBox(null,Ie("giftBox",1));console.log("Obtained 100 conjure cubes.");for(var o=0;o<100;o++)r.achievements.data.progress[o]=10;console.log("Obtained all achievements."),r.data.tower=100,console.log("Set tower floor to 100."),we(1),ge(),l.fire("Success!","All items added!","success"),console.log("All items added!"),r.backpack.data.mount=Y(c.gameData.mount,1),console.log("Added all mounts.");let s="currency",a=6969420;return r.backpack.data[s]=Y(c.gameData[s].filter(d=>s==="follow"?!Ee.includes(d.ID):d),a),fe(),console.log("Added all pets."),r.equipment.setHat(200),r.equipment.setBoots(93),r.equipment.setOutfit(161),r.equipment.setWeapon(196),r.appearanceChanged=!0,console.log("Appearance Refreshed."),$(),console.log("Character Saved."),console.log("Max Account Successful."),l.fire("Maxed!","Check your backpack!","success")});new p(u.player,"Set Gold").setClick(async()=>{let e=await b.fire("Gold Amount","What number do you want to set your gold to?","question");if(e.value!==void 0)return e.value>1e7?l.fire("Error","Cannot have more than 10,000,000 gold.","error"):(r.data.gold=+e.value,l.fire("Success!",`You now have ${e.value} gold.`,"success"))});new p(u.player,"Set Magicoin","Set your Magicoin amount.").setClick(async()=>{let e=await b.fire("Magicoin Amount","What number do you want to set your Magicoin to?","question");if(e.value!==void 0)try{return r._secureInventory._cacheByPath.currency[27].stackable.quantity=+e.value,l.fire("Done!",`Magicoin set to ${e.value}.`,"success")}catch{return g.fire("Error","Failed to set Magicoin. The path may have changed.","error")}});new p(u.player,"Set Level").setClick(async()=>{let e=await b.fire("Level","What number do you want to set your level to?","question");if(e.value===void 0)return;if(e.value===1)return 0;let t=e.value-2,n=1.042;return r.data.stars=Math.round((1-Math.pow(n,t))/(1-n)*20+10),r.data.level=+e.value,r.getLevel=()=>r.data.level,l.fire("Success!",`You are now level ${e.value}.`,"success")});new p(u.player,"Get member stars").setClick(async()=>{let e=await b.fire("Stars","How many member stars do you want?","question");if(e.value!==void 0)return r.data.storedMemberStars=e.value,l.fire("Success!",`You have set your member stars to ${e.value}.`,"success")});new p(u.player,"Set Bounty Points").setClick(async()=>{let e=await b.fire("Bounty Points","What number do you want to set your bounty points to? (Max is 100)","question");if(e.value!==void 0)return r.data.bountyScore=Math.min(+e.value,100),l.fire("Success!",`You now have ${r.data.bountyScore} bounty point${r.data.bountyScore!=1?"s":""}.`,"success")});new p(u.player,"Set Wins").setClick(async()=>{let e=await b.fire("Wins","What number do you want to set your wins to?","question");if(e.value!==void 0)return r.data.win=+e.value,l.fire("Success!",`You have set your win${e.value!=1?"s":""} to ${e.value}.`,"success")});new p(u.player,"Set Losses").setClick(async()=>{let e=await b.fire("Losses","What number do you want to set your losses to?","question");if(e.value!==void 0)return r.data.loss=+e.value,l.fire("Success!",`You have set your loss${e.value!=1?"es":""} to ${e.value}.`,"success")});var Pe=null;new k(u.player,"Toggle Membership (Client Side)").setEnabled(async()=>c.functions?.setMembership?.(!0)?(Pe||(Pe=r.getMemberTier?.bind(r)),r.getMemberTier=()=>103,r.appearanceChanged=!0,l.fire({icon:"success",title:"Membership enabled (cosmetic)",html:"Use Selector (Advanced) to get member-only items."})):l.fire("Error","Membership service not found.","error")).setDisabled(()=>c.functions?.setMembership?.(!1)?(Pe&&(r.getMemberTier=Pe,Pe=null),r.appearanceChanged=!0,l.fire("Success!","You no longer have Prodigy membership!","success")):l.fire("Error","Membership service not found.","error"));new p(u.player,"Set name (Client side only)").setClick(async()=>{let e=await K.fire("What would you like to set your name to?");if(e.value)return r.getName=()=>e.value,r.appearanceChanged=!0,l.fire("Changed!","Your name was changed.")});new p(u.player,"Change Name","Change the name of your wizard.").setClick(async()=>{let e=c.gameData.name,t=document.createElement("div"),n=(a,d)=>{let m=document.createElement("select");m.classList.add("selectName");for(let f of a.entries()){let I=document.createElement("option");[I.value,I.innerText]=f,d(I.value)&&(I.selected=!0),m.options.add(I)}return m},o=(a,d)=>n(new Map(e.filter(m=>m.data.type===a).map(m=>[m.ID.toString(),m.name])),m=>d(+m));t.append(o(0,a=>a===r.name.data.firstName)),t.append(o(1,a=>a===r.name.data.middleName)),t.append(o(2,a=>a===r.name.data.lastName)),t.append(n(new Map([["null","[none]"]].concat(c.gameData.nickname.map(a=>[a.ID.toString(),a.name]))),a=>+a===r.name.data.nickname||String(r.name.data.nickname)===a));let s=await g.fire({title:"Set Player Name",focusConfirm:!1,showCancelButton:!0,html:t,preConfirm:()=>Array.prototype.slice.call(document.querySelectorAll(".selectName")).map(a=>a.options[a.selectedIndex].value)});if(s.value!==void 0)return s.value[3]==="null"&&(s.value[3]=null),[r.name.data.firstName,r.name.data.middleName,r.name.data.lastName,r.name.data.nickname]=s.value.map(a=>a&&+a),r.appearanceChanged=!0,l.fire("Name Changed!","Your name was successfully changed.","success")});new p(u.player,"Uncap player level (client side only)").setClick(async()=>{let e=await b.fire("Level","What would you like to set your level to? (Can be >100)","question");if(e.value)return localStorage.setItem("level",e.value),r.getLevel=()=>Number(e.value),l.fire("Updated!","Your level has been successfully updated","success")});new p(u.player,"Get all achievements").setClick(async()=>{for(var e=0;e<100;e++)r.achievements.data.progress[e]=10;return l.fire("Success!","Obtained all achievements!","success")});new p(u.player,"Fix Morph Crash").setClick(async()=>(r.getPlayerData().playerTransformation=void 0,r.appearanceChanged=!0,l.fire("Success!","Fixed morph crash bug.","success")));new p(u.player,"Permanent Morph","Makes Your Current Morph Last Forever.").setClick(async()=>r.data.playerTransformation?(r.data.playerTransformation.maxTime=1/0,r.data.playerTransformation.timeRemaining=1/0,l.fire("Success!","You're morph will last forever!","success")):g.fire("No Morph Active","Please use a Morph Marble and try again.","error"));new p(u.player,"Morph Player [BETA]","Morph into a pet, furnishing, or follow.").setClick(async()=>{if(!(await E.fire("This hack is in BETA","Expect bugs, and it might not work properly.")).value)return console.log("Cancelled");let e=await g.fire({title:"Which morph type?",input:"select",inputOptions:{pet:"Pet",dorm:"Furniture",follow:"Follow"},inputPlaceholder:"Morph Type",inputValidator:o=>o?"":"Please select a morph type.",showCancelButton:!0});if(!e?.value)return;let t={};c.gameData[e.value].forEach(o=>t[o.ID]=`${o.name} (${o.ID})`);let n=await g.fire({title:"Which morph?",input:"select",inputOptions:t,inputPlaceholder:"Morph ID",inputValidator:o=>o?"":"Please select a morph ID.",showCancelButton:!0});if(n.value)return r.getPlayerData().playerTransformation={transformType:e.value,transformID:n.value,maxTime:3600*1e3,timeRemaining:3600*1e3},r.appearanceChanged=!0,l.fire("Morphed!","You've been morphed.","success")});new p(u.player,"Complete Current Task In Quest","Completes current task in quest. (Use this button a lot to complete a quest.)").setClick(async()=>{let e={};Object.keys(c.instance.prodigy.world.zones).forEach(o=>{e[o]=c.instance.prodigy.world.zones[o].name});let t=(await K.fire({title:"What Quest Do You Want To Complete?",input:"select",inputOptions:e})).value;if(!t)return;let n=c.instance.prodigy.world.zones[t].getCurrentQuestID();return c.instance.prodigy.world.zones[t].completeQuest(n)?(c.instance.prodigy.world.goToZoneHub(t),l.fire("Success!",`Completed current task in the ${c.instance.prodigy.world.zones[t].name} quest successfully!`,"success")):l.fire("Could Not Complete Current Task In Quest.","There was an error completing the quest. Did you already complete it?","error")});new p(u.player,"Set Dark Tower Floor").setClick(async()=>{let e=await b.fire({title:"What floor do you want to be on, in the dark tower.",icon:"question",inputValidator:t=>t>100||t<1?`You can only be on floors from 1-100 not ${t}`:!1});if(e.value)return r.data.tower=parseInt(e.value),l.fire("Success!",`Successfully set dark tower floor to ${e}!`,"success")});new p(u.player,"Get UserID").setClick(async()=>{let e=r.userID;navigator.clipboard.writeText(e.toString()).then(function(){return console.log("Async: Copying to clipboard was successful!"),g.fire({title:"User ID",html:`Here is your User ID:
      ${e}
      You can use this for copying your account.

      Your UserID is has also been copied to your clipboard.`,icon:"info"})},function(t){return console.error("Async: Could not copy text: ",t),g.fire({title:"User ID",html:`Here is your User ID:
      ${e}
      You can use this for copying your account.`,icon:"info"})})});new p(u.player,"Copy Account","Copy Account From userID").setClick(async()=>{let e=(await b.fire("What is the userID of the account you want to copy?",void 0,"question")).value;if(!e)return;let t=await fetch(`https://api.prodigygame.com/game-api/v2/characters/${e}?fields=inventory%2Cdata%2CisMember%2Ctutorial%2Cpets%2Cencounters%2Cquests%2Cappearance%2Cequipment%2Chouse%2Cachievements%2Cstate&userID=${e}`,{headers:{Authorization:localStorage.JWT_TOKEN}});if(!t.ok)return l.fire("Error",`Failed to fetch account data: ${t.status} ${t.statusText}`,"error");let n=await t.json();if(!n[e])return l.fire("Error",`Account #${e} not found or data is invalid.`,"error");if((await E.fire("WARNING: This operation is IRREVERSIBLE!",`You are about to overwrite ALL of your character data with account #${e}. +`;Ue.style.color="white";pe.append(Ue);var u={player:q("Player Mods"),inventory:q("Inventory Mods"),location:q("Location Mods"),pets:q("Pet Mods"),battle:q("Battle Mods"),battlepass:q("Battle Pass Mods"),minigames:q("Minigame Mods"),misc:q("Miscellaneous Mods"),utility:q("Utility Mods"),beta:q("Beta Testing | Beta Mods may damage your account")};localStorage.hasTip?console.log("Player already has tip."):((async()=>await Q.fire({title:"Welcome!",html:"To get started with the hacks, click this dropdown!",icon:"info"}))(),localStorage.hasTip=!0,console.log("Player was shown the tip."));localStorage.getItem("level")&&(c.player.getLevel=()=>localStorage.getItem("level"),console.log("Loaded menu from localStorage."));window.__ORIGIN_ABORT__?.abort();var Ln=new AbortController;window.__ORIGIN_ABORT__=Ln;var yt=!0;document.addEventListener("keydown",function(e){e.key=="Shift"&&(e.stopImmediatePropagation(),console.log("Shift key was pressed."),yt==!0?(console.log("Hiding mod menu..."),document.getElementById("origin-menu").style.display="none",document.getElementById("origin-toggler").style.display="none",yt=!1,console.log("Hidden mod menu.")):(console.log("Showing mod menu..."),document.getElementById("origin-menu").style.display="block",document.getElementById("origin-toggler").style.display="block",yt=!0,console.log("Shown mod menu.")))},{capture:!0,signal:Ln.signal});var p=class{constructor(t,n,o){this.parent=t;this.name="",this.description="",this.element=document.createElement("button"),this.element.classList.add("menu-hack"),this.parent.append(this.element),n&&this.setName(n),o&&this.setDesc(o)}parent;element;name;description;setName(t){return this.element.innerText=t,this.name=t,this}setClick(t){return this.element.onclick=async()=>{await t(),$(),console.log(`Triggered ${this.name}.`)},this}setDesc(t){return this.element.title=t,this.description=t,this}};var k=class extends p{constructor(n,o,s){super(n,o,s);this.parent=n;this.element.setAttribute("status","false"),this.migrateOldKey(),this.setClick(async()=>{this.status=!this.status,this.status?(localStorage.setItem(this.getStorageKey(),"true"),await this.enabled?.()):(localStorage.setItem(this.getStorageKey(),"false"),await this.disabled?.())})}parent;enabled;disabled;migrateOldKey(){let n=this.getStorageKey();this.name!==n&&localStorage.getItem(this.name)!==null&&(localStorage.setItem(n,localStorage.getItem(this.name)),localStorage.removeItem(this.name))}getStorageKey(){let n=this.parent.querySelector("h1")?.innerText??"";return n?`${n}::${this.name}`:this.name}get status(){return JSON.parse(this.element.getAttribute("status"))}set status(n){this.element.setAttribute("status",n.toString())}setEnabled(n){if(this.enabled=n,localStorage.getItem(this.getStorageKey())==="true")try{this.element.click()}catch(o){console.warn(`[Origin] Failed to restore toggle state for "${this.name}":`,o)}return this}setDisabled(n){return this.disabled=n,this}};var g=Q,K=g.mixin({input:"text",showCancelButton:!0,showConfirmButton:!0,toast:!1}),b=K.mixin({toast:!1,input:"number"}),l=g.mixin({toast:!0,position:"bottom"}),E=g.mixin({icon:"warning",showCancelButton:!0,toast:!1,confirmButtonText:"Confirm",cancelButtonText:"Cancel"}),Ys=g.mixin({icon:"info",showCancelButton:!1,toast:!1});window.Swal=g;function F(e,t){let n=c.constants;return!n||typeof n.set!="function"?!1:(n.set(e,t),!0)}new k(u.battle,"Instant Kill [PvE]","Makes your spells do insane damage in PvE!").setEnabled(async()=>(r.modifiers.damage=P,l.fire("Enabled!","You will now do insane damage in PvE!","success"))).setDisabled(()=>(r.modifiers.damage=1,l.fire("Disabled!","You will no longer do insane damage in PvE!","success")));new p(u.battle,"PvP Health [PvP]","Increases your HP in PvP by a hell ton.").setClick(async()=>(r.pvpHP=P,r.getMaxHearts=()=>P,l.fire("Success!","You now have lots of health!","success")));new p(u.battle,"Set Battle Hearts [PvP, PvE]","Sets your hearts in battle, automatically raise your max hearts in PvP or PvE.").setClick(async()=>{let e=await b.fire("Health Amount","How much HP do you want?","question");if(e.value!==void 0)return r.getMaxHearts=()=>+e.value,r.pvpHP=+e.value,r.data.hp=+e.value,l.fire("Success!","Your hearts have been set.","success")});new p(u.battle,"Fill Battle Energy [PvP, PvE]","Fills up your battle energy, if you are in PvP or PvE.").setClick(async()=>{let e=Ae.state.getCurrentState();return"teams"in e?(e.teams[0].setEnergy(99),l.fire("Success!","Your battle energy has been filled.","success")):l.fire("Error","You are currently not in a battle.","error")});new k(u.battle,"Disable math [PvP, PvE]","Disable math in PvP, PvE, anywhere! This doesn't work in the Floatling town.").setEnabled(async()=>F("GameConstants.Debug.EDUCATION_ENABLED",!1)?l.fire("Enabled!","You will no longer do Math!","success"):l.fire("Error","FlagProvider service not found.","error")).setDisabled(async()=>(F("GameConstants.Debug.EDUCATION_ENABLED",!0),l.fire("Disabled!","You will now do Math!","success")));new k(u.battle,"Skip enemy turn").setEnabled(async()=>F("GameConstants.Battle.SKIP_ENEMY_TURN",!0)?l.fire("Skipping!","Enemy turns will now be skipped.","success"):l.fire("Error","FlagProvider service not found.","error")).setDisabled(async()=>(F("GameConstants.Battle.SKIP_ENEMY_TURN",!1),l.fire("Disabled","Enemy turns will no longer be skipped.","success")));new p(u.battle,"Escape Battle [PvP, PvE]","Escape any battle, PvP or PvE!").setClick(async()=>{let e=Ae.state.current;if(e==="PVP")return Object.fromEntries(c.instance.game.state.states).PVP.endPVP(),l.fire("Escaped!","You have successfully escaped from the PvP battle.","success");if(e==="CoOp")return c.instance.prodigy.world.$(r.data.zone),l.fire("Escaped!","You have successfully escaped from the battle.","success");if(e==="SecureBattleRevamp"){let t=c.instance?._game?._state?._current?._battleController;return!t||typeof t.attemptEscape!="function"?l.fire("Error","BattleController not available on current state.","error"):(await t.attemptEscape(),l.fire("Escaped!","You have successfully escaped from the PvE battle.","success"))}return["Battle","SecureBattle"].includes(e)?(Object.fromEntries(c.instance.game.state.states)[e].runAwayCallback(),l.fire("Escaped!","You have successfully escaped from the PvE battle.","success")):l.fire("Invalid State.","You are currently not in a battle.","error")});new p(u.battle,"Win Battle [PvE]","Instantly win the current PvE battle.").setClick(async()=>{if(Ae.state.current!=="SecureBattleRevamp")return l.fire("Invalid State.","You are currently not in a PvE battle.","error");let e=c.instance?.game?._state?._current?._battleController;return!e||typeof e.onVictory!="function"?l.fire("Error","BattleController not available on current state.","error"):(await e.onVictory(),l.fire("Victory!","You won the battle!","success"))});function Ts(){let e=c?.prodigy??c?.instance?.prodigy;return e?._currentBattlePass??e?._battlePass??null}function bt(e){let t=Ts();if(!t||typeof t!="object")return g.fire("Error","Battle Pass not found.","error");let n=t._tiers;return!n||typeof n!="object"?g.fire("Error","Tiers not found in battle pass.","error"):(Object.values(n).forEach(o=>{o&&(o.isCompleted=!0,o[e]&&(o[e].claimed=!1,o[e].claimable=!0))}),l.fire("Success!","Rewards unlocked.","success"))}new p(u.battlepass,"Treasure Free","Unlocks all free Battle Pass tier rewards.").setClick(async()=>bt("freeReward"));new p(u.battlepass,"Treasure Core","Unlocks all Core (bottom premium) Battle Pass tier rewards.").setClick(async()=>bt("bottomPremiumReward"));new p(u.battlepass,"Treasure Plus","Unlocks all Plus (top premium) Battle Pass tier rewards.").setClick(async()=>bt("topPremiumReward"));var W=["Boots","Buddies","Fossils","Hats","Items","Key Items","Tower Town Frames","Tower Town Interiors","Mounts","Outfits","Relics","Weapons","Currencies"],C=["boots","follow","fossil","hat","item","key","mathTownFrame","mathTownInterior","mount","outfit","spellRelic","weapon","currency"],Y=(e,t)=>e.map(n=>({ID:n.ID,N:t})).filter(n=>n!==void 0),Mn=(e,t)=>e.map(n=>({ID:n.ID,quantity:t})).filter(n=>n!==void 0);function $n(e){if(c.player.userID!==e){let n=c.instance.prodigy.friendsListNetworkHandler.friendsList.length,o=c.instance.prodigy.friendsListNetworkHandler.classList.length;c.instance.prodigy.gameContainer.get("2e1-e659").create("house-visit","click","hub",n,o,null,null,e).broadcast()}let t=c.instance.prodigy.world.getZone(c.instance.prodigy.world.getCurrentZone());return t?t.handleLeaving(2,()=>Ds(e)):g.fire({title:"Error",text:"You are not in a zone!",icon:"error"})}function Ds(e){c.instance.prodigy.loading(!0);let t=n=>{let o=n!=null?n[e]:null;if(o!==null&&o.house!==void 0&&o.house!==null){c.instance.prodigy.loading(!1);let s=c.cloneDeep(c.player.house);return s.setItems(o.house),o.data.allowsHouseVisitors!==void 0&&o.data.allowsHouseVisitors!==null&&o.data.allowsHouseVisitors?c.instance.prodigy.world._("house",null,null,{house:s,getAllowsHouseVisitors:()=>o.data.allowsHouseVisitors!==void 0&&o.data.allowsHouseVisitors!==null?o.data.allowsHouseVisitors:!1,setAllowsHouseVisitors:a=>{o.data.allowsHouseVisitors=a}}):g.fire(`Teleporting to ${e} is not allowed.`,"Try another user.","error")}};return c.network.getCharData(e.toString(),["house","data"],t,t),l.fire("Teleported to house","You have been teleported to the house!","success")}var Ge=async e=>(await g.fire({input:"select",inputOptions:new Map(c.player.kennel.data.map((n,o)=>[o.toString(),`Level ${n.level} - ${n.nickname??c.gameData.pet.find(s=>+s.ID==+n.ID)?.data.name??"Unknown"}`])),title:"Choose Pet",text:e})).value,Ee=[125,126,127,128,129,134,135,136,137];function me(){c.gameData.pet.forEach(e=>{r.kennel.addPet(e.ID,P,26376,100)}),r.kennel._encounterInfo._data.pets=[],c.gameData.pet.map(e=>{r.kennel._encounterInfo._data.pets.push({firstSeenDate:Date.now(),ID:e.ID,timesBattled:1,timesRescued:1})}),r.kennel.petTeam.forEach(e=>{e&&e.assignRandomSpells&&e.assignRandomSpells()})}function fe(e){C.forEach(t=>{r.backpack.data[t]=Y(c.gameData[t].filter(n=>t==="follow"?!Ee.includes(n.ID):n),e)}),c.gameData.dorm.forEach(t=>r.house.data.items[t.ID]={A:[],N:e})}function we(){let e=()=>r.backpack.data.item.findIndex(t=>t.ID===84||t.ID===85||t.ID===86);for(;e()>-1;)r.backpack.data.item.splice(e(),1)}var On=!1;function vt(e){On=e}(async()=>setInterval(async()=>{On&&c.instance.prodigy.open.menuCloseAll()},200))();new p(u.beta,"Edit Pet [BETA]","Edit a pet.").setClick(async()=>{if(!(await E.fire({title:"Hang on!",html:"This hack may damage your account with various bugs, for example you may be unable to do Rune Run.

      Proceed?",icon:"warning"})).value)return console.log("Cancelled.");let e=await Ge("Choose the pet to edit.");if(e===void 0)return;let t=r.kennel.data[e],n=await g.fire({input:"select",inputOptions:{level:"Level",attacks:"Attacks",name:"Name"},title:"Edit Property",text:"What do you want to edit?"});if(n.value!==void 0){if(n.value==="level"){let o=await b.fire("Level Number","What level do you want to set your pet to?","question");return o.value===void 0?void 0:(t.level=+o.value,l.fire("Success!","The pet's level has been set.","success"))}else if(n.value==="attacks"){let o=c.gameData.spell,s=document.createElement("div"),a=document.createElement("select");a.classList.add("selectSpell");for(let m of o){let f=document.createElement("option");f.value=m.ID.toString(),f.innerText=`${m.ID}: ${m.name} (${m.data.element}) - Damage: ${m.data.damage}`,a.options.add(f)}s.append(a),s.append(a.cloneNode(!0));let d=await g.fire({title:"Attack List",focusConfirm:!1,showCancelButton:!0,html:s,preConfirm:()=>Array.prototype.slice.call(document.querySelectorAll(".selectSpell")).map(m=>m.options[m.selectedIndex].value)});return d.value===void 0?void 0:(t.foreignSpells.splice(0,2,...d.value.map(m=>+m)),l.fire("Attacks updated!","The attack list of the pet you selected has been edited.","success"))}else if(n.value==="name"){let o=await K.fire("Input Name","What do you want to name the pet?","question");return o.value===void 0?void 0:(t.nickname=o.value,l.fire("Successfully renamed!","The name of the pet has been changed.","success"))}}});new k(u.beta,"(client side) Toggle Invisibility [BETA]","Lets you appear invisible on your own screen.").setEnabled(async()=>{he.user.visible=!1}).setDisabled(async()=>{he.user.visible=!0});new k(u.beta,"Toggle Close Popups [BETA]","Automatically closes popups in Prodigy.").setEnabled(async()=>(vt(!0),l.fire("Enabled","Toggle Close Popups is now enabled.","success"))).setDisabled(async()=>(vt(!1),l.fire("Enabled","Toggle Close Popups is now disabled.","success")));new p(u.beta,"Hypermax Account [BETA]").setClick(async()=>{if(!(await E.fire({title:"Hang on!",html:"This hack will damage your account with various bugs, for example you may be unable to do Rune Run/Arena, amd you will recieve 418s and inavtivity kicks.

      Proceed?",icon:"warning"})).value)return;r.data.gold=99e5,console.log("Set player gold to 9900000.");let t=100-2,n=1.042;r.data.stars=Math.round((1-Math.pow(n,t))/(1-n)*20+10),r.data.level=100,r.getLevel=()=>r.data.level,console.log("Set player level to 100"),r.data.bountyScore=100,console.log("Set player's bounty points to 100.");for(let f=0;f<99;f++)V.giftBoxController.receiveGiftBox(null,Ie("giftBox",1));console.log("Obtained 100 conjure cubes."),r.data.win=P,console.log("Set player's wins to VERY_LARGE_NUMBER"),r.data.loss=0,console.log("Set player's losses to 0."),r.modifiers.damage=P,console.log("Enabled damage multiplier."),r.pvpHP=P,r.getMaxHearts=()=>P,console.log("PvP health obtained.");for(var o=0;o<100;o++)r.achievements.data.progress[o]=10;console.log("Obtained all achievements."),r.data.tower=100,console.log("Set tower floor to 100."),r.getMaxHearts=()=>P,r.pvpHP=P,r.data.hp=P,console.log("Maxed out PvE health."),fe(99e4),we(),l.fire("Success!","All items added!","success"),console.log("All items added!"),r.backpack.data.mount=Y(c.gameData.mount,1),console.log("Added all mounts."),me(),console.log("Added all pets."),c.gameData.pet.filter(f=>[158,166,168].includes(f.ID)).forEach(f=>{r.kennel.addPet(f.ID,P,26376,100)}),r.kennel.petTeam.forEach(f=>{f&&f.assignRandomSpells&&f.assignRandomSpells()}),console.log("Added Mythical Epics."),c.gameData.pet.filter(f=>[125,126,127,128,129,130,131,132,133].includes(f.ID)).forEach(f=>{r.kennel.addPet(f.ID,P,26376,100)}),r.kennel.petTeam.forEach(f=>{f&&f.assignRandomSpells&&f.assignRandomSpells()}),console.log("Added Legacy Epics."),c.constants.constants["GameConstants.Inactivity.LOG_OUT_TIMER_SECONDS"]=0,console.log("Inactivity Kick Disabled."),r._playerContainer.walkSpeed=20,console.log("Player walkspeed set to 20.");let d=100,m;return Array.from(c.instance.prodigy.gameContainer._inversifyContainer._bindingDictionary._map).forEach(f=>{try{c.instance.prodigy.gameContainer.get(f[0]).battleData&&(m=f[0])}catch{console.log(`Error for ${f[0]}`)}}),c.instance.prodigy.gameContainer.get(m).battleData._secureCharacterState._data.inventory.orb=Mn(c.gameData.orb,d),r.equipment.setHat(200),r.equipment.setBoots(93),r.equipment.setOutfit(161),r.equipment.setWeapon(196),$(),console.log("Character Saved."),r.appearanceChanged=!0,console.log("Appearance Refreshed."),c.instance.prodigy.open.menuCloseAll(),console.log("Popups closed."),$(),console.log("Character Saved."),console.log("Max Account Successful."),l.fire("Maxed!","Check your backpack!","success")});new p(u.inventory,"Item stacker").setClick(async()=>{let e=await b.fire("Amount","How many of every item would you like?","question");if(e.value&&(await E.fire("Are you sure you want to get all items in the game?")).value)return fe(e.value),we(),l.fire("Success!","All items added!","success")});new p(u.inventory,"Clear inventory").setClick(async()=>{(await E.fire("Are you sure you want to clear your inventory?")).value&&(Object.keys(r.backpack.data).forEach(e=>r.backpack.data[e]=[]),l.fire("Success!","Inventory cleared.","success"))});new p(u.inventory,"Selector (Basic)").setClick(async()=>{let e=await g.fire({title:"What would you like to obtain?",input:"select",inputOptions:W,inputPlaceholder:"Select...",inputValidator:t=>t?"":"Please select which you'd like to obtain.",showCancelButton:!0}).then(async t=>{let n=parseInt(t.value),o=W[n],s=C[n];if(!o)return;let a=await b.fire("Amount","How many each object would you like?","question");a.value&&(await E.fire(`Are you sure you want to get all ${o.toLowerCase()}?`)).value&&(r.backpack.data[s]=Y(c.gameData[s].filter(d=>s==="follow"?!Ee.includes(d.ID):d),a.value),l.fire(`${o} Added!`,`All ${o.toLowerCase()} have been added to your inventory!`,"success"),$())})});new p(u.inventory,"Selector (Advanced)","Choose a specific object and quantity to obtain.").setClick(async()=>{let e=await g.fire({title:"What would you like to obtain?",input:"select",inputOptions:W,inputPlaceholder:"Select...",inputValidator:t=>t?"":"Please select which you'd like to obtain.",showCancelButton:!0}).then(async t=>{if(!c.gameData[C[t.value]])return;let n=[];c.gameData[C[t.value]].forEach(s=>{n.push(s.data.name)});let o=await g.fire({title:`What specific object categorized as ${W[t.value].toLowerCase()} would you like to get?`,input:"select",inputOptions:n,inputPlaceholder:"Select...",inputValidator:s=>s?"":"Please select which you'd like to get.",showCancelButton:!0}).then(async s=>{let a=parseInt(s.value);if(!c.gameData[C[t.value]][a])return;let d=await b.fire("Amount","How many of the object would you like?","question");if(!d.value)return;let m=r.backpack.data[C[t.value]].findIndex(f=>f.ID===c.gameData[C[t.value]][a].ID);return m===-1?r.backpack.data[C[t.value]].push({ID:c.gameData[C[t.value]][a].ID,N:d.value}):r.backpack.data[C[t.value]][m].N=d.value,console.log(c.gameData[C[t.value]][a].ID),$(),l.fire(`${W[t.value]} Added!`,`Your selected ${W[t.value].toLowerCase()} have been added.`,"success")})})});new p(u.inventory,"Obtain All Furniture").setClick(async()=>{let e=await b.fire("Amount","How many of each piece of furniture would you like?","question");if(e.value&&(await E.fire("Are you sure you want to get all furniture?")).value)return c.gameData.dorm.forEach(t=>r.house.data.items[t.ID]={A:[],N:e.value}),l.fire("Furniture Added!","All furniture has been added to your inventory!","success")});new p(u.inventory,"Obtain All Mounts","This gives you all of the mounts in the game.").setClick(async()=>(r.backpack.data.mount=Y(c.gameData.mount,1),l.fire("Mounts Added!","All mounts have been added to your inventory!")));new p(u.inventory,"Remove item").setClick(async()=>{let e=await g.fire({title:"What category would you like to remove an item from?",input:"select",inputOptions:W,inputPlaceholder:"Select...",inputValidator:a=>a?"":"Please select which you'd like to obtain.",showCancelButton:!0});if(!c.gameData[C[e.value]])return;let t=c.gameData[C[e.value]].map(a=>a.data.name),n=await g.fire({title:`What specific object categorized as ${W[e.value].toLowerCase()} would you like to remove?`,input:"select",inputOptions:t,inputPlaceholder:"Select...",inputValidator:a=>a?"":"Please select which you'd like to get.",showCancelButton:!0});if(n=parseInt(n.value),!c.gameData[C[e.value]][n])return;let o=await b.fire("Amount","How many of the object would you like to remove?","question");if(!o.value)return;if(r.backpack.data[C[e.value]].findIndex(a=>a.ID===c.gameData[C[e.value]][n].ID)===-1){await g.fire("Item Does Not Exist",`You do not have any ${c.gameData[C[e.value]][n].name}.`,"error");return}let s=r.backpack.data[C[e.value]].findIndex(a=>a.ID===c.gameData[C[e.value]][n].ID);return r.backpack.data[C[e.value]][s].N-=parseInt(o.value),r.backpack.data[C[e.value]][s].N<=0&&r.backpack.data[C[e.value]].splice(s,1),$(),l.fire("Removed!",`Successfully removed ${o.value} ${c.gameData[C[e.value]][n].name}!`,"success")});new p(u.inventory,"Get All Gems","Adds one of each gem type to your backpack and saves.").setClick(async()=>([3,4,10,11,17].forEach(t=>{let n=r.backpack.data.key.find(o=>o.ID===t);n?n.N+=1:r.backpack.data.key.push({ID:t,N:1})}),r.appearance.updated=!0,r.updated=!0,r.saveEnabled=!0,typeof r.forceSaveCharacter=="function"&&r.forceSaveCharacter(),r.appearanceChanged=!0,r.backpack.updated=!0,l.fire("Done!","All gems added to your backpack.","success")));var Ke=!0;new k(u.location,"WASD Movement","Allows you to walk through walls or on air with WASD movement in Prodigy.").setEnabled(async()=>(Ke=!0,l.fire("Enabled!","WASD Movement is now enabled.","success"))).setDisabled(async()=>(Ke=!1,l.fire("Disabled!","WASD Movement is now disabled.","success"))).status=!0;new p(u.location,"Edit walkspeed","Lets you set your walkspeed.").setClick(async()=>{let e=await K.fire("What do you want to set your walk speed to?");if(e.value){if(r._playerContainer)r._playerContainer.walkSpeed=parseFloat(e.value)||1.5;else{let t=setInterval(()=>{r._playerContainer&&(clearInterval(t),r._playerContainer.walkSpeed=parseFloat(e.value))},100)}return l.fire("Success!",`Successfully made walk speed ${parseFloat(e.value)||1.5}!`,"success")}});var Hn=-1;new k(u.location,"Toggle Click Teleporting").setEnabled(async()=>(Hn=setInterval(()=>{try{r._playerContainer.walkSpeed=500}catch{}},16),l.fire("Success!","Successfully enabled teleport click.","success"))).setDisabled(async()=>(clearInterval(Hn),r._playerContainer.walkSpeed=1.5,l.fire("Success!","Successfully disabled teleport click.","success")));new p(u.location,"Teleport To Map (interactive)").setClick(async()=>{let e=g.mixin({focusConfirm:!1,showCancelButton:!0,preConfirm:()=>document.querySelector(".radioDiv[checked]")?.getAttribute("zone")}),t=document.createElement("div");t.classList.add("radioContainer");for(let m of Object.keys(V.world.zones)){let f=document.createElement("DIV");f.classList.add("radioDiv"),f.setAttribute("zone",m),f.innerText=m,f.onclick=()=>{document.querySelectorAll(".radioDiv[checked]").forEach(I=>I.removeAttribute("checked")),f.setAttribute("checked","")},t.append(f)}let n=await e.fire({title:"Teleport Zone",html:t,customClass:{popup:"radioSwal"}});if(!n.value)return;let o=Object.keys(V.world.zones[n.value].maps),s=await g.fire({input:"select",inputOptions:new Map(o.map(m=>[m,m])),title:"Map",text:"Which map in the zone do you want to teleport to?"});if(!s.value)return;let a=(await b.fire("Please enter the x to teleport to. (Try 500?)")).value||500,d=(await b.fire("Please enter the y to teleport to. (Try 500?)")).value||500;return V.world.zones[n.value].teleport(s.value,a,d,{},{}),l.fire("Teleported","You have been teleported!","success")});new p(u.location,"Teleport to house by userID").setClick(async()=>{let e=(await b.fire("Please enter the userID.")).value;if(e)return $n(e),l.fire("Teleported!","You have been teleported!","success")});new p(u.location,"Get Map Location").setClick(async()=>{let e=r.data.zone;navigator.clipboard.writeText(e).then(async function(){return console.log("Async: Copying to clipboard was successful!"),g.fire({title:"Map Location",html:`You are at
      ${e} .
      You can save this to get to the same zone.

      Your location is has also been copied to your clipboard.`,icon:"info"})},async function(t){return console.error("Async: Could not copy text: ",t),g.fire({title:"Map Location",html:`You are at
      ${e} .
      You can save this to get to the same zone.`,icon:"info"})})});new k(u.minigames,"69x Walk Speed [Dyno Dig]","Walk so fast that you're teleporting, in Dyno Dig.").setEnabled(async()=>(c.instance.game.state.states.get("DinoDig").walkSpeed=69,l.fire("Enabled!","You will now walk so fast that you're teleporting in Dyno Dig.","success"))).setDisabled(async()=>(c.instance.game.state.states.get("DinoDig").walkSpeed=1.5,l.fire("Disabled!","You will now walk at normal speed, in Dyno Dig.","success")));new p(u.minigames,"Dino Dig +100 Days","Adds 100 days to the active Dino Dig timer.").setClick(async()=>{let e=c.instance.game.state.states.get("DinoDig");return e?.timer?.addTime?(e.timer.addTime(864e7),l.fire("Done!","Added 100 days to the Dino Dig timer.","success")):g.fire("Error","You are not currently in Dino Dig.","error")});new p(u.minigames,"End Dino Dig","Instantly ends the current Dino Dig session.").setClick(async()=>{let e=c.instance.game.state.states.get("DinoDig");return e?.timer?.addTime?(e.timer.addTime(-9e15),l.fire("Done!","Dino Dig session ended.","success")):g.fire("Error","You are not currently in Dino Dig.","error")});var kt=document.createElement("button"),Se=null;function _n(){Se||Bs()}function Nn(){Se&&(clearInterval(Se),Se=null),document.getElementById("fps-counter")?.remove()}function Bs(){kt.id="fps-counter",We?.prepend(kt),Se=setInterval(()=>{kt.innerText=r.game.fps._framerate.toFixed(2)+" FPS"},300)}new p(u.misc,"Skip Tutorial").setClick(async()=>{let e=(t,n,o,s)=>{c.instance.prodigy.world.getZone(t).testQuest(n,o,s);try{Object.fromEntries(c.instance.game.state.states).TileScreen.process()}catch{}};e("house",2),e("academy",2),r.state.set("tutorial-0",4),r.backpack.addKeyItem(13,0),r.tutorial.data.menus[14]=[1],c.instance.prodigy.open.map(!0,[]),r.onTutorialComplete(),r.data.level=Math.max(r.data.level,5)});new k(u.beta,"FPS Counter [BETA]","Shows you a framerate counter").setEnabled(async()=>{_n()}).setDisabled(async()=>{Nn()});try{let e=null;new k(u.misc,"Unlimited Spins","Lets you spin the wheel as many times as you want!").setEnabled(async()=>(e=r.canSpin,r.canSpin=()=>!0,l.fire("Enabled!","You can now spin the wheel as many times as you want!","success"))).setDisabled(async()=>(r.canSpin=e,l.fire("Disabled!","You can now spin the wheel only when allowed.","success")))}catch(e){console.error("Unlimited Spins ERROR: "+e)}new p(u.misc,"Reset Account","Completely resets your account.").setClick(async()=>{if((await E.fire("Are you sure you want to reset your account?","This action is not reversible.")).value)return r.resetAccount(),g.fire("Reset!","Your account has been reset. Reload Prodigy for the full effect.","success")});new p(u.misc,"[Fix] Fix Battle Crash").setClick(async()=>(r.kennel.petTeam.forEach(e=>{e&&e.assignRandomSpells&&e.assignRandomSpells()}),l.fire("Success!","Fixed kennel attack bug!","success")));new p(u.misc,"[Fix] Stuck in Unfinished Tower Fix","Takes you out of an unfinished tower if you're stuck in one.").setClick(async()=>(c.instance.prodigy.world.zones.house.teleport("exit"),l.fire("Success!","You've been teleported outside of your house.","success")));new k(u.misc,"Disable Monster Encounters").setEnabled(async()=>F("GameConstants.Debug.SCALE_ENCOUNTER_DISTANCE",0)?l.fire("Enabled!","Monsters will no longer battle you.","success"):l.fire("Error","FlagProvider service not found.","error")).setDisabled(()=>(F("GameConstants.Debug.SCALE_ENCOUNTER_DISTANCE",1),l.fire("Disabled!","Monsters will now battle you.","success")));new p(u.misc,"Bobbified","Turns you into Bobby Fancywoman (level 69, specific appearance).").setClick(async()=>{if((await E.fire("Are you sure?","You will be transformed into Bobby Fancywoman.")).value)return r.name.data.firstName=44,r.name.data.middleName=754,r.name.data.lastName=882,r.data.stars=-1e22,r.data.level=69,r.appearance.setEyeColor(1),r.appearance.setFace(4),r.appearance.setHair(19,1),r.appearance.setSkinColor(1),r.equipment.setFollow(19),r.equipment.setHat(19),r.equipment.setBoots(19),r.equipment.setOutfit(19),r.equipment.setWeapon(19),l.fire("Done!","You are now Bobby Fancywoman.","success")});new p(u.pets,"Get All Pets").setClick(async()=>(await E.fire("Would you like to add all pets to your pets?")).value?(me(),l.fire("Success!","All pets have been added!","success")):console.log("Cancelled"));new p(u.pets,"Get All Legacy Epics").setClick(async()=>(await E.fire({title:"This may damage your account.",html:"Attempting to add legacy epics may damage your account.

      Warning: this does NOT save on reload — the pets will disappear after refreshing.

      Would you still like to add all legacy epics to your team?",icon:"warning"})).value?(c.gameData.pet.filter(t=>[125,126,127,128,129,130,131,132,133].includes(t.ID)).forEach(t=>{r.kennel.addPet(t.ID,P,26376,100)}),r.kennel.petTeam.forEach(t=>{t&&t.assignRandomSpells&&t.assignRandomSpells()}),l.fire("Success!","All legacy epics have been added!","success")):console.log("Cancelled"));new p(u.pets,"Get All Mythical Epics").setClick(async()=>(await E.fire({title:"Add all mythical epics?",html:"Warning: this does NOT save on reload — the pets will disappear after refreshing.

      Would you like to add all mythical epics to your pets?",icon:"warning"})).value?(c.gameData.pet.filter(t=>[158,164,165,166,167,168,169,170,171,189].includes(t.ID)).forEach(t=>{r.kennel.addPet(t.ID,P,26376,100)}),r.kennel.petTeam.forEach(t=>{t&&t.assignRandomSpells&&t.assignRandomSpells()}),l.fire("Success!","All mythical epics have been added!","success")):console.log("Cancelled"));new p(u.pets,"Clear Pets").setClick(async()=>(await E.fire("Would you like to delete all of your pets?")).value?(r.kennel.data.length=0,l.fire("Success!","Your pets have been cleared!","success")):console.log("Cancelled"));new p(u.pets,"Add Pet","Adds a pet from a list.").setClick(async()=>{let e=await g.fire({input:"select",inputOptions:new Map(c.gameData.pet.map(t=>[t.ID.toString(),`${t.ID}: ${t.data.name}`])),title:"Choose Pet",text:"Which pet do you want to obtain?"});if(e.value!==void 0)return r.kennel.addPet(e.value),r.kennel._encounterInfo._data.pets.push({firstSeenDate:Date.now(),ID:e.value,timesBattled:1,timesRescued:1}),l.fire("Success!","Your chosen pet has been added to your pets!","success")});new p(u.pets,"Uncap pet level [Client Side]","Change your pet's level to anything, even over 100. This hack won't save when you reload Prodigy.").setClick(async()=>{let e=r.kennel.petTeam.slice(0);e.shift();let t=e.map(a=>a.getName()),n=await g.fire({title:"Which pet would you like to edit?",input:"select",inputOptions:t,inputPlaceholder:"Select...",inputValidator:a=>a?"":"Please select which you'd like to obtain.",showCancelButton:!0}),o=await b.fire("Level","What would you like to set your pet's level to? (Can be set over 100)","question");if(!o.value)return;let s=o.value;return r.kennel.petTeam[parseInt(n.value)+1].getLevel=()=>Number(s),l.fire("Updated!","The level of your pet was successfully updated. Note: this hack is client-side.","success")});new p(u.pets,"Delete Pet","Delete a pet.").setClick(async()=>{let e=await Ge("Which pet do you wish to delete?");if(e!==void 0)return r.kennel.data.splice(e,1),l.fire("Successfully deleted!","The selected pet was deleted successfully.","success")});new p(u.pets,"All Pets Level 150","Replaces all pets with every pet at level 150. WARNING: Erases current pet data.").setClick(async()=>{if((await E.fire("Are you sure?","This will erase all your current pet data and replace it with every pet at level 150.")).value)try{let e=(d,m)=>Math.floor(Math.random()*(m-d+1)+d),t=(d,m)=>{let f=m.data.statHealth,I=500/1.25*Math.pow(Math.pow(1.25,.25),f-1),ge=100/1.25*Math.pow(Math.pow(1.25,.25),f-1);return Math.ceil(I+(d-1)*ge)},s=(d=>{if(d===1)return 0;if(d===2)return 10;let m=d-2,f=1.042;return Math.round((1-Math.pow(f,m))/(1-f)*20+10)})(150),a=c.gameData.pet;return r.kennel.data.length=0,a.forEach(d=>{r.kennel.addPet(d.ID,t(150,d),s,150)}),r.kennel._encounterInfo._data.pets=a.map(d=>({firstSeenDate:Date.now()-e(2e4,12e4),ID:d.ID,timesBattled:1,timesRescued:1,rescueAttempts:1})),r.kennel.petTeam.forEach(d=>{d&&d.assignRandomSpells&&d.assignRandomSpells()}),g.fire("Done!","All pets added at level 150. Leave the game open for ~2 minutes to fully sync.","success")}catch(e){return g.fire("Error","Failed to add pets: "+e,"error")}});new p(u.player,"Max Account").setClick(async()=>{if(!(await E.fire("Are you sure that you want to max your account?","We recommend doing this on an alt.")).value)return console.log("Cancelled");r.data.gold=99e5,console.log("Set player gold to 9900000.");let t=100-2,n=1.042;r.data.stars=Math.round((1-Math.pow(n,t))/(1-n)*20+10),r.data.level=100,r.getLevel=()=>r.data.level,console.log("Set player level to 100"),r.data.bountyScore=100,console.log("Set player's bounty points to 100.");for(let d=0;d<99;d++)V.giftBoxController.receiveGiftBox(null,Ie("giftBox",1));console.log("Obtained 100 conjure cubes.");for(var o=0;o<100;o++)r.achievements.data.progress[o]=10;console.log("Obtained all achievements."),r.data.tower=100,console.log("Set tower floor to 100."),fe(1),we(),l.fire("Success!","All items added!","success"),console.log("All items added!"),r.backpack.data.mount=Y(c.gameData.mount,1),console.log("Added all mounts.");let s="currency",a=6969420;return r.backpack.data[s]=Y(c.gameData[s].filter(d=>s==="follow"?!Ee.includes(d.ID):d),a),me(),console.log("Added all pets."),r.equipment.setHat(200),r.equipment.setBoots(93),r.equipment.setOutfit(161),r.equipment.setWeapon(196),r.appearanceChanged=!0,console.log("Appearance Refreshed."),$(),console.log("Character Saved."),console.log("Max Account Successful."),l.fire("Maxed!","Check your backpack!","success")});new p(u.player,"Set Gold").setClick(async()=>{let e=await b.fire("Gold Amount","What number do you want to set your gold to?","question");if(e.value!==void 0)return e.value>1e7?l.fire("Error","Cannot have more than 10,000,000 gold.","error"):(r.data.gold=+e.value,l.fire("Success!",`You now have ${e.value} gold.`,"success"))});new p(u.player,"Set Magicoin","Set your Magicoin amount.").setClick(async()=>{let e=await b.fire("Magicoin Amount","What number do you want to set your Magicoin to?","question");if(e.value!==void 0)try{return r._secureInventory._cacheByPath.currency[27].stackable.quantity=+e.value,l.fire("Done!",`Magicoin set to ${e.value}.`,"success")}catch{return g.fire("Error","Failed to set Magicoin. The path may have changed.","error")}});new p(u.player,"Set Level").setClick(async()=>{let e=await b.fire("Level","What number do you want to set your level to?","question");if(e.value===void 0)return;if(e.value===1)return 0;let t=e.value-2,n=1.042;return r.data.stars=Math.round((1-Math.pow(n,t))/(1-n)*20+10),r.data.level=+e.value,r.getLevel=()=>r.data.level,l.fire("Success!",`You are now level ${e.value}.`,"success")});new p(u.player,"Get member stars").setClick(async()=>{let e=await b.fire("Stars","How many member stars do you want?","question");if(e.value!==void 0)return r.data.storedMemberStars=e.value,l.fire("Success!",`You have set your member stars to ${e.value}.`,"success")});new p(u.player,"Set Bounty Points").setClick(async()=>{let e=await b.fire("Bounty Points","What number do you want to set your bounty points to? (Max is 100)","question");if(e.value!==void 0)return r.data.bountyScore=Math.min(+e.value,100),l.fire("Success!",`You now have ${r.data.bountyScore} bounty point${r.data.bountyScore!=1?"s":""}.`,"success")});new p(u.player,"Set Wins").setClick(async()=>{let e=await b.fire("Wins","What number do you want to set your wins to?","question");if(e.value!==void 0)return r.data.win=+e.value,l.fire("Success!",`You have set your win${e.value!=1?"s":""} to ${e.value}.`,"success")});new p(u.player,"Set Losses").setClick(async()=>{let e=await b.fire("Losses","What number do you want to set your losses to?","question");if(e.value!==void 0)return r.data.loss=+e.value,l.fire("Success!",`You have set your loss${e.value!=1?"es":""} to ${e.value}.`,"success")});var Pe=null;new k(u.player,"Toggle Membership (Client Side)").setEnabled(async()=>c.functions?.setMembership?.(!0)?(Pe||(Pe=r.getMemberTier?.bind(r)),r.getMemberTier=()=>103,r.appearanceChanged=!0,l.fire({icon:"success",title:"Membership enabled (cosmetic)",html:"Use Selector (Advanced) to get member-only items."})):l.fire("Error","Membership service not found.","error")).setDisabled(()=>c.functions?.setMembership?.(!1)?(Pe&&(r.getMemberTier=Pe,Pe=null),r.appearanceChanged=!0,l.fire("Success!","You no longer have Prodigy membership!","success")):l.fire("Error","Membership service not found.","error"));new p(u.player,"Set name (Client side only)").setClick(async()=>{let e=await K.fire("What would you like to set your name to?");if(e.value)return r.getName=()=>e.value,r.appearanceChanged=!0,l.fire("Changed!","Your name was changed.")});new p(u.player,"Change Name","Change the name of your wizard.").setClick(async()=>{let e=c.gameData.name,t=document.createElement("div"),n=(a,d)=>{let m=document.createElement("select");m.classList.add("selectName");for(let f of a.entries()){let I=document.createElement("option");[I.value,I.innerText]=f,d(I.value)&&(I.selected=!0),m.options.add(I)}return m},o=(a,d)=>n(new Map(e.filter(m=>m.data.type===a).map(m=>[m.ID.toString(),m.name])),m=>d(+m));t.append(o(0,a=>a===r.name.data.firstName)),t.append(o(1,a=>a===r.name.data.middleName)),t.append(o(2,a=>a===r.name.data.lastName)),t.append(n(new Map([["null","[none]"]].concat(c.gameData.nickname.map(a=>[a.ID.toString(),a.name]))),a=>+a===r.name.data.nickname||String(r.name.data.nickname)===a));let s=await g.fire({title:"Set Player Name",focusConfirm:!1,showCancelButton:!0,html:t,preConfirm:()=>Array.prototype.slice.call(document.querySelectorAll(".selectName")).map(a=>a.options[a.selectedIndex].value)});if(s.value!==void 0)return s.value[3]==="null"&&(s.value[3]=null),[r.name.data.firstName,r.name.data.middleName,r.name.data.lastName,r.name.data.nickname]=s.value.map(a=>a&&+a),r.appearanceChanged=!0,l.fire("Name Changed!","Your name was successfully changed.","success")});new p(u.player,"Uncap player level (client side only)").setClick(async()=>{let e=await b.fire("Level","What would you like to set your level to? (Can be >100)","question");if(e.value)return localStorage.setItem("level",e.value),r.getLevel=()=>Number(e.value),l.fire("Updated!","Your level has been successfully updated","success")});new p(u.player,"Get all achievements").setClick(async()=>{for(var e=0;e<100;e++)r.achievements.data.progress[e]=10;return l.fire("Success!","Obtained all achievements!","success")});new p(u.player,"Fix Morph Crash").setClick(async()=>(r.getPlayerData().playerTransformation=void 0,r.appearanceChanged=!0,l.fire("Success!","Fixed morph crash bug.","success")));new p(u.player,"Permanent Morph","Makes Your Current Morph Last Forever.").setClick(async()=>r.data.playerTransformation?(r.data.playerTransformation.maxTime=1/0,r.data.playerTransformation.timeRemaining=1/0,l.fire("Success!","You're morph will last forever!","success")):g.fire("No Morph Active","Please use a Morph Marble and try again.","error"));new p(u.player,"Morph Player [BETA]","Morph into a pet, furnishing, or follow.").setClick(async()=>{if(!(await E.fire("This hack is in BETA","Expect bugs, and it might not work properly.")).value)return console.log("Cancelled");let e=await g.fire({title:"Which morph type?",input:"select",inputOptions:{pet:"Pet",dorm:"Furniture",follow:"Follow"},inputPlaceholder:"Morph Type",inputValidator:o=>o?"":"Please select a morph type.",showCancelButton:!0});if(!e?.value)return;let t={};c.gameData[e.value].forEach(o=>t[o.ID]=`${o.name} (${o.ID})`);let n=await g.fire({title:"Which morph?",input:"select",inputOptions:t,inputPlaceholder:"Morph ID",inputValidator:o=>o?"":"Please select a morph ID.",showCancelButton:!0});if(n.value)return r.getPlayerData().playerTransformation={transformType:e.value,transformID:n.value,maxTime:3600*1e3,timeRemaining:3600*1e3},r.appearanceChanged=!0,l.fire("Morphed!","You've been morphed.","success")});new p(u.player,"Complete Current Task In Quest","Completes current task in quest. (Use this button a lot to complete a quest.)").setClick(async()=>{let e={};Object.keys(c.instance.prodigy.world.zones).forEach(o=>{e[o]=c.instance.prodigy.world.zones[o].name});let t=(await K.fire({title:"What Quest Do You Want To Complete?",input:"select",inputOptions:e})).value;if(!t)return;let n=c.instance.prodigy.world.zones[t].getCurrentQuestID();return c.instance.prodigy.world.zones[t].completeQuest(n)?(c.instance.prodigy.world.goToZoneHub(t),l.fire("Success!",`Completed current task in the ${c.instance.prodigy.world.zones[t].name} quest successfully!`,"success")):l.fire("Could Not Complete Current Task In Quest.","There was an error completing the quest. Did you already complete it?","error")});new p(u.player,"Set Dark Tower Floor").setClick(async()=>{let e=await b.fire({title:"What floor do you want to be on, in the dark tower.",icon:"question",inputValidator:t=>t>100||t<1?`You can only be on floors from 1-100 not ${t}`:!1});if(e.value)return r.data.tower=parseInt(e.value),l.fire("Success!",`Successfully set dark tower floor to ${e}!`,"success")});new p(u.player,"Get UserID").setClick(async()=>{let e=r.userID;navigator.clipboard.writeText(e.toString()).then(function(){return console.log("Async: Copying to clipboard was successful!"),g.fire({title:"User ID",html:`Here is your User ID:
      ${e}
      You can use this for copying your account.

      Your UserID is has also been copied to your clipboard.`,icon:"info"})},function(t){return console.error("Async: Could not copy text: ",t),g.fire({title:"User ID",html:`Here is your User ID:
      ${e}
      You can use this for copying your account.`,icon:"info"})})});new p(u.player,"Copy Account","Copy Account From userID").setClick(async()=>{let e=(await b.fire("What is the userID of the account you want to copy?",void 0,"question")).value;if(!e)return;let t=await fetch(`https://api.prodigygame.com/game-api/v2/characters/${e}?fields=inventory%2Cdata%2CisMember%2Ctutorial%2Cpets%2Cencounters%2Cquests%2Cappearance%2Cequipment%2Chouse%2Cachievements%2Cstate&userID=${e}`,{headers:{Authorization:localStorage.JWT_TOKEN}});if(!t.ok)return l.fire("Error",`Failed to fetch account data: ${t.status} ${t.statusText}`,"error");let n=await t.json();if(!n[e])return l.fire("Error",`Account #${e} not found or data is invalid.`,"error");if((await E.fire("WARNING: This operation is IRREVERSIBLE!",`You are about to overwrite ALL of your character data with account #${e}. This action CANNOT be undone. The source account data has not been reviewed. -Are you absolutely sure?`)).value)try{let o=await fetch(`https://api.prodigygame.com/game-api/v3/characters/${e}`,{headers:{"Content-Type":"application/json",Authorization:localStorage.JWT_TOKEN},body:JSON.stringify({data:JSON.stringify(n[e]),userID:r.userID}),method:"POST"});return o.ok?l.fire("Success!","Copied Account Successfully! Please reload.","success"):l.fire("Error",`Failed to copy account: ${o.status} ${o.statusText}`,"error")}catch(o){return l.fire("Error",`Network error while copying account: ${o instanceof Error?o.message:"Unknown error"}`,"error")}});new p(u.player,"Set Grade").setClick(async()=>{let e=await b.fire("What number do you want to set your grade to?");if(e.value)return r.grade=parseInt(e.value),l.fire("Success",`Successfully changed grade to ${e}!`,"success")});new p(u.utility,"Close all popups","Closes all popups in Prodigy.").setClick(async()=>(c.instance.prodigy.open.menuCloseAll(),l.fire("Closed!","All open popups were closed.","success")));new p(u.utility,"Grab UserID of all players on screen","Shows you the UserID and name of every player currently shown on the screen.").setClick(async()=>{let e=he.playerList;if(Object.keys(e).length===0)return l.fire("No players found.","There are no other players on the screen.","error");let t=document.createElement("ul");for(let[n,o]of Object.entries(e)){let s="Unknown";try{s=o.nameText.textSource.source}catch{}let a=document.createElement("li");a.textContent=`uID: ${n} - ${s}`,t.append(a)}return g.fire({title:"All players on the screen:",html:t,icon:"info"})});new p(u.utility,"Save Character Locally [Local]","Saves your character locally.").setClick(async()=>(localStorage.setItem("playerData",JSON.stringify(r.getUpdatedData(!0))),l.fire("Success!","Note: Load Character will only work on this device.","success")));new p(u.utility,"Load local character [Local]","Loads your character locally.").setClick(async()=>{if(localStorage.getItem("playerData")){let e=localStorage.getItem("playerData"),t=await fetch(`https://api.prodigygame.com/game-api/v3/characters/${r.userID}`,{headers:{accept:"*/*","accept-language":"en-US,en;q=0.9",authorization:localStorage.JWT_TOKEN,"content-type":"application/json"},referrer:"https://play.prodigygame.com/",referrerPolicy:"strict-origin-when-cross-origin",body:JSON.stringify({data:e,userID:r.userID}),method:"POST",mode:"cors"});return t.ok?l.fire("Success!","Character has been successfully loaded. Reload for the changes to take effect.","success"):l.fire("Request failed.",`An error occurred while loading the character. Error code: ${t.status}`,"error")}else return l.fire("Error","No saved character.","error")});new p(u.utility,"Save Character","Helps fix bugs where not all hacks save.").setClick(async()=>($(),l.fire("Success!","Your character has been saved!","success")));new k(u.utility,"Enable menu resize","Allows you to resize the menu via dragging the bottom right corner.").setEnabled(async()=>(document.getElementById("origin-menu").style.resize="both",l.fire("Success!","Drag the bottom right corner of the menu to resize it.","success"))).setDisabled(()=>(document.getElementById("origin-menu").style.resize="none",l.fire("Success!","The menu position is now locked.","success")));new k(u.utility,"Pause Game").setEnabled(async()=>(c.network.game._paused=!0,l.fire("Success!","Successfully paused Prodigy.","success"))).setDisabled(async()=>(c.network.game._paused=!1,l.fire("Success!","Successfully resumed Prodigy.","success")));new p(u.utility,"Disable inactivity kick","Keeps you from being logged out for inactivity.").setClick(async()=>F("GameConstants.Inactivity.LOG_OUT_TIMER_SECONDS",0)?l.fire("Success!","You now will never be logged out!","success"):l.fire("Error","FlagProvider service not found.","error"));new p(u.utility,"Save Inventory","Forces a server-side save of your inventory/backpack.").setClick(async()=>{try{return r.updated=!0,r.saveEnabled=!0,r.backpack&&(r.backpack.updated=!0),typeof r.save=="function"&&await r.save(),l.fire("Saved!","Inventory saved to server.","success")}catch(e){return g.fire("Error","Failed to save inventory: "+e,"error")}});new p(u.utility,"Save Pet Data","Forces a server-side save of your pet/kennel data.").setClick(async()=>(r.kennel.updated=!0,r.updated=!0,r.saveEnabled=!0,typeof r.forceSaveCharacter=="function"&&r.forceSaveCharacter(),l.fire("Saved!","Pet data saved to server.","success")));window.addEventListener("keydown",e=>{switch(e.key){case"`":c.instance.prodigy.open.menuCloseAll();break;case"\\":(async()=>{if(!(await E.fire("Kit","Would you like to equip Celestial Gear?")).value)return console.log("Cancelled");c.player.equipment.setHat(200),c.player.equipment.setBoots(93),c.player.equipment.setOutfit(161),c.player.equipment.setWeapon(196),c.player.appearanceChanged=!0,l.fire("Success!","You are now wearing Celestial Armor and wielding a Dual Blade.","success")})();break}});async function qn(e){for(let t=0;t<100;t++)await new Promise(n=>setTimeout(n,2)),r._playerContainer.x-=e/100}async function Fn(e){for(let t=0;t<100;t++)await new Promise(n=>setTimeout(n,2)),r._playerContainer.y-=e/100}window.addEventListener("keydown",e=>{if(Ke)switch(e.key){case"w":Fn(40);break;case"s":Fn(-40);break;case"a":qn(40);break;case"d":qn(-40);break}});})(); +Are you absolutely sure?`)).value)try{let o=await fetch(`https://api.prodigygame.com/game-api/v3/characters/${e}`,{headers:{"Content-Type":"application/json",Authorization:localStorage.JWT_TOKEN},body:JSON.stringify({data:JSON.stringify(n[e]),userID:r.userID}),method:"POST"});return o.ok?l.fire("Success!","Copied Account Successfully! Please reload.","success"):l.fire("Error",`Failed to copy account: ${o.status} ${o.statusText}`,"error")}catch(o){return l.fire("Error",`Network error while copying account: ${o instanceof Error?o.message:"Unknown error"}`,"error")}});new p(u.player,"Set Grade").setClick(async()=>{let e=await b.fire("What number do you want to set your grade to?");if(e.value)return r.grade=parseInt(e.value),l.fire("Success",`Successfully changed grade to ${e}!`,"success")});new p(u.utility,"Close all popups","Closes all popups in Prodigy.").setClick(async()=>(c.instance.prodigy.open.menuCloseAll(),l.fire("Closed!","All open popups were closed.","success")));new p(u.utility,"Grab UserID of all players on screen","Shows you the UserID and name of every player currently shown on the screen.").setClick(async()=>{let e=he.playerList;if(Object.keys(e).length===0)return l.fire("No players found.","There are no other players on the screen.","error");let t=document.createElement("ul");for(let[n,o]of Object.entries(e)){let s="Unknown";try{s=o.nameText.textSource.source}catch{}let a=document.createElement("li");a.textContent=`uID: ${n} - ${s}`,t.append(a)}return g.fire({title:"All players on the screen:",html:t,icon:"info"})});new p(u.utility,"Save Character Locally [Local]","Saves your character locally.").setClick(async()=>(localStorage.setItem("playerData",JSON.stringify(r.getUpdatedData(!0))),l.fire("Success!","Note: Load Character will only work on this device.","success")));new p(u.utility,"Load local character [Local]","Loads your character locally.").setClick(async()=>{if(localStorage.getItem("playerData")){let e=localStorage.getItem("playerData"),t=await fetch(`https://api.prodigygame.com/game-api/v3/characters/${r.userID}`,{headers:{accept:"*/*","accept-language":"en-US,en;q=0.9",authorization:localStorage.JWT_TOKEN,"content-type":"application/json"},referrer:"https://play.prodigygame.com/",referrerPolicy:"strict-origin-when-cross-origin",body:JSON.stringify({data:e,userID:r.userID}),method:"POST",mode:"cors"});return t.ok?l.fire("Success!","Character has been successfully loaded. Reload for the changes to take effect.","success"):l.fire("Request failed.",`An error occurred while loading the character. Error code: ${t.status}`,"error")}else return l.fire("Error","No saved character.","error")});new p(u.utility,"Save Character","Helps fix bugs where not all hacks save.").setClick(async()=>($(),l.fire("Success!","Your character has been saved!","success")));new k(u.utility,"Enable menu resize","Allows you to resize the menu via dragging the bottom right corner.").setEnabled(async()=>(document.getElementById("origin-menu").style.resize="both",l.fire("Success!","Drag the bottom right corner of the menu to resize it.","success"))).setDisabled(()=>(document.getElementById("origin-menu").style.resize="none",l.fire("Success!","The menu position is now locked.","success")));new k(u.utility,"Pause Game").setEnabled(async()=>(c.network.game._paused=!0,l.fire("Success!","Successfully paused Prodigy.","success"))).setDisabled(async()=>(c.network.game._paused=!1,l.fire("Success!","Successfully resumed Prodigy.","success")));new p(u.utility,"Disable inactivity kick","Keeps you from being logged out for inactivity.").setClick(async()=>F("GameConstants.Inactivity.LOG_OUT_TIMER_SECONDS",0)?l.fire("Success!","You now will never be logged out!","success"):l.fire("Error","FlagProvider service not found.","error"));new p(u.utility,"Save Inventory","Forces a server-side save of your inventory/backpack.").setClick(async()=>{try{return r.updated=!0,r.saveEnabled=!0,r.backpack&&(r.backpack.updated=!0),typeof r.save=="function"&&await r.save(),l.fire("Saved!","Inventory saved to server.","success")}catch(e){return g.fire("Error","Failed to save inventory: "+e,"error")}});new p(u.utility,"Save Pet Data","Forces a server-side save of your pet/kennel data.").setClick(async()=>(r.kennel.updated=!0,r.updated=!0,r.saveEnabled=!0,typeof r.forceSaveCharacter=="function"&&r.forceSaveCharacter(),l.fire("Saved!","Pet data saved to server.","success")));window.addEventListener("keydown",e=>{switch(e.key){case"`":c.instance.prodigy.open.menuCloseAll();break;case"\\":(async()=>{if(!(await E.fire("Kit","Would you like to equip Celestial Gear?")).value)return console.log("Cancelled");c.player.equipment.setHat(200),c.player.equipment.setBoots(93),c.player.equipment.setOutfit(161),c.player.equipment.setWeapon(196),c.player.appearanceChanged=!0,l.fire("Success!","You are now wearing Celestial Armor and wielding a Dual Blade.","success")})();break}});async function Rn(e){for(let t=0;t<100;t++)await new Promise(n=>setTimeout(n,2)),r._playerContainer.x-=e/100}async function zn(e){for(let t=0;t<100;t++)await new Promise(n=>setTimeout(n,2)),r._playerContainer.y-=e/100}window.addEventListener("keydown",e=>{if(Ke)switch(e.key){case"w":zn(40);break;case"s":zn(-40);break;case"a":Rn(40);break;case"d":Rn(-40);break}});})(); diff --git a/originGUI/src/hacks/location.ts b/originGUI/src/hacks/location.ts index 36fd748..fdb9f53 100644 --- a/originGUI/src/hacks/location.ts +++ b/originGUI/src/hacks/location.ts @@ -5,7 +5,7 @@ import { category } from "../index"; // Import the mod menu bases. import Toggler from "../class/Toggler"; import Hack from "../class/Hack"; import { Input, NumberInput, Swal, Toast } from "../utils/swal"; // Import Swal, Toast, and NumberInput from swal -import { _, locations, prodigy, player } from "../utils/util"; // Import Prodigy typings +import { _, prodigy, player } from "../utils/util"; // Import Prodigy typings import { toHouse } from "../utils/hackify"; // Import toHouse // END IMPORTS @@ -96,10 +96,8 @@ new Hack(category.location, "Teleport To Map (interactive)").setClick( const radio = document.createElement("DIV"); radio.classList.add("radioDiv"); radio.setAttribute("zone", zone); - const locationURL = locations[zone as keyof typeof locations]; - if (locationURL) { - radio.style.backgroundImage = `url(${locationURL})`; - } else radio.innerText = zone; + // Zone art used to load from GitHub; Prodigy's CSP blocks that, so label by name. + radio.innerText = zone; radio.onclick = () => { document .querySelectorAll(".radioDiv[checked]") diff --git a/originGUI/src/index.ts b/originGUI/src/index.ts index 726111c..7d18ef7 100644 --- a/originGUI/src/index.ts +++ b/originGUI/src/index.ts @@ -3,7 +3,6 @@ import "./style.scss"; // Import SCSS style import { _ } from "./utils/util"; // Import Prodigy typings -import { statusMessage } from "./utils/status"; // Import status message import Swal from "sweetalert2"; // Import Swal @@ -168,6 +167,4 @@ document.addEventListener("keydown", function (event) { -// Display status message. -statusMessage(); From 24c14870c900ac0e1ede3bf61e2816b244103455 Mon Sep 17 00:00:00 2001 From: Alexey Fedorov Date: Thu, 24 Sep 2026 13:10:49 -0500 Subject: [PATCH 10/11] chore(extension): drop P-NP pipeline, URL overrides and unused permissions from Chrome build Also removes the menu's dead GitHub asset map and status-message fetch, and documents the packaged runtime (CLAUDE.md, architecture, workflow, spec amendment for the CSP finding). Co-Authored-By: Claude Opus 5.5 --- .claude/architecture.md | 58 +++--- .claude/workflow.md | 4 +- CLAUDE.md | 7 +- ...26-09-24-chrome-packaged-runtime-design.md | 6 +- extension/lib/bundle-cache.ts | 45 ----- extension/lib/manifest.ts | 53 ------ extension/lib/patch-urls.ts | 18 -- extension/lib/patches.ts | 42 ----- extension/package.json | 7 +- extension/popup.tsx | 167 +----------------- extension/tests/bundle-cache.test.ts | 82 --------- extension/tests/integration.test.ts | 81 --------- extension/tests/manifest.test.ts | 88 --------- extension/tests/patch-urls.test.ts | 72 -------- extension/tests/patches.test.ts | 64 ------- originGUI/dist/bundle.js | 18 +- originGUI/src/utils/status.ts | 30 ---- originGUI/src/utils/util.ts | 26 --- 18 files changed, 56 insertions(+), 812 deletions(-) delete mode 100644 extension/lib/bundle-cache.ts delete mode 100644 extension/lib/manifest.ts delete mode 100644 extension/lib/patch-urls.ts delete mode 100644 extension/lib/patches.ts delete mode 100644 extension/tests/bundle-cache.test.ts delete mode 100644 extension/tests/integration.test.ts delete mode 100644 extension/tests/manifest.test.ts delete mode 100644 extension/tests/patch-urls.test.ts delete mode 100644 extension/tests/patches.test.ts delete mode 100644 originGUI/src/utils/status.ts diff --git a/.claude/architecture.md b/.claude/architecture.md index 2a646c6..2b66fe4 100644 --- a/.claude/architecture.md +++ b/.claude/architecture.md @@ -2,16 +2,14 @@ ## Packages -- **originGUI/** — In-game mod menu (TypeScript, bundled with esbuild). Injected into the Prodigy game page. -- **extension/** — Plasmo-based MV3 Chrome extension (Play Origin): - - Blocks original `game.min.js` via declarativeNetRequest - - Removes CSP/X-Frame-Options headers - - Injects patched game code + mod menu bundle via the `onreset` attribute trick - - Custom login background and logo redirects - - Fetches `manifest.json` from the sibling `P-NP` repo's `dist/` - - Fetches the original `game.min.js` directly from `code.prodigygame.com` - - Applies the manifest's regex rules + wraps with prefix/suffix in the background service worker - - Caches the patched result in `chrome.storage.local` keyed by `{gameClientVersion, manifestHash}` +- **originGUI/** — In-game mod menu (TypeScript, bundled with esbuild). `build.mjs` also emits `dist/menu.js` (gitignored): the bundle wrapped as `export default function startOriginMenu()` so the extension can package it. +- **extension/** — Plasmo-based MV3 Chrome extension (Play Origin). On branch `chrome/packaged-runtime` it runs no remote code: + - Prodigy loads its own, unmodified `game.min.js` + - `contents/runtime.ts` (MAIN world, `document_start`) wraps `Object.defineProperty` to capture webpack export objects, resolves hook targets by shape/name, installs the education bypasses and builds `window._` + - `contents/menu.ts` (MAIN world, `document_idle`) runs the packaged originGUI on `origin:ready` + - `background.ts` only registers two DNR redirects that swap the login background and logo for packaged, web-accessible art + - Prodigy's CSP is left intact + - Master still ships the old P-NP `manifest.json` + `onreset` pipeline for Edge/Firefox - **typings/** — Reverse-engineered TypeScript type definitions for Prodigy's game objects - **meta/** — Documentation, guides @@ -19,13 +17,21 @@ - **Package manager:** pnpm. Workspace defined in `pnpm-workspace.yaml`. - **Build tools:** esbuild for originGUI, Plasmo for extension -- **Injection method:** `document.documentElement.setAttribute("onreset", code)` + `dispatchEvent(new CustomEvent("reset"))` + `removeAttribute("onreset")` — bypasses MV3 CSP restrictions -- **Content script:** runs in `world: "MAIN"` via `chrome.scripting.registerContentScripts()` from the background service worker -- **DNR rules:** registered dynamically in `extension/background.ts` via `chrome.declarativeNetRequest.updateDynamicRules()` +- **Content scripts:** Plasmo registers the MAIN-world scripts with `chrome.scripting.registerContentScripts()` from the service worker +- **DNR rules:** registered dynamically in `extension/background.ts` via `chrome.declarativeNetRequest.updateDynamicRules()` (ids 3, 4: `extensionPath` redirects) - **Log prefix:** `[Origin]` in all console output -- **Window globals:** `__ORIGIN_INJECTED__`, `__ORIGIN_REWRITTEN__`, `__ORIGIN_GAME_URL__`, `__ORIGIN_GUI_URL__` -- **DOM attributes:** `data-origin-game-url`, `data-origin-gui-url`, `data-origin-ready`, `data-origin` -- **Storage keys:** `originGameUrl`, `originGuiUrl` +- **Window globals:** `_` (lodash, plus Play Origin's `instance`, `constants`, `player`, `network`, `gameData`, `membership`, `functions.setMembership`), `__ORIGIN_READY__` +- **Events:** `origin:ready` on `window` + +### Hook targets (`extension/lib/runtime/resolve.ts`) + +| Target | Found by | Used for | +|---|---|---| +| `singletonClass` | class with static `instance` getter and `prodigy` prototype getter | `_.instance`, service discovery | +| `constants` | `.constants` object owning `"GameConstants.Build.VERSION"` | `_.constants`, bypass gate | +| `componentRegistry` | object whose `OpenQuestionInterface` is a class (`EV()` decorator registry) | battle question bypass | +| `baseActionClass` | class whose prototype owns `init`, `execute`, `finish`, `findParameter`, `validateParameters` | `AnswerQuestion` action bypass | +| `towerTownClass` | class owning `openQuestionInterfaceThenEmitNotifications` | Tower Town bypass | ## Related Repos @@ -35,17 +41,19 @@ ``` extension/ - background.ts — Service worker: DNR rules registration - contents/prodigy.ts — Content script (MAIN world): game + mod menu injection - contents/origin-bridge.ts — Bridge script (ISOLATED world): URL communication + background.ts — Service worker: DNR login-art redirects only + contents/runtime.ts — MAIN world, document_start: hook + resolve + bypasses + window._ + contents/menu.ts — MAIN world, document_idle: starts packaged originGUI on origin:ready popup.tsx — Extension popup UI package.json — Plasmo config + manifest overrides - lib/ - patch-urls.ts — MANIFEST_URL + game-URL regex helpers - patches.ts — applyPatchRules + wrapWithPrefixSuffix - manifest.ts — Manifest type + validateManifest - bundle-cache.ts — chrome.storage.local cache wrapper - tests/ — unit + integration tests (node --test) + assets/origin-*.png — Packaged login background and logo (web-accessible) + lib/runtime/ + modules.ts — defineProperty hook capturing webpack export objects + resolve.ts — hook target resolvers + bypasses.ts — education bypass prototype wraps + api.ts — window._ API (ported from P-NP wrappers.ts) + ready.ts — origin:ready signal + tests/ — unit tests (node --test) originGUI/ build.mjs — esbuild build script src/index.ts — Entry point diff --git a/.claude/workflow.md b/.claude/workflow.md index 315867b..db8ae4c 100644 --- a/.claude/workflow.md +++ b/.claude/workflow.md @@ -21,4 +21,6 @@ cd extension && pnpm dev - Load unpacked extension from `extension/build/chrome-mv3-dev/` (dev) or `extension/build/chrome-mv3-prod/` (prod) - Navigate to https://math.prodigygame.com/ to test - Check browser console for `[Origin]` log messages -- Verify DNR rules are active: chrome://extensions → service worker → inspect +- Network tab: `code.prodigygame.com/code/*/game.min.js` is 200 (loaded by Prodigy, not blocked) +- Console: `[Origin] packaged runtime active`, three `[Origin] hook installed:` lines, no `hook target missing`, then `[Origin] menu started` +- Console check: `[!!_.instance?.prodigy, _.constants.get("GameConstants.Build.VERSION"), !!_.player?.data, window.__ORIGIN_READY__]` diff --git a/CLAUDE.md b/CLAUDE.md index 1313bcc..fe60831 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -14,9 +14,10 @@ Monorepo for modding online math games (formerly modding Prodigy Math Game), mai 2. **No force pushes**, no history rewrites 3. **esbuild** for originGUI, **Plasmo** for extension — no webpack 4. **MV3 only** — use declarativeNetRequest, not webRequest -5. The **`onreset` injection trick** is intentional and critical — do not replace it with script tags or other methods -6. **Graceful degradation** — if patches fail, set `patchDegraded: true` and open a GitHub issue -7. **Dev bundle guard** — before committing `originGUI/dist/bundle.js`, confirm it does NOT end with `/* DEV BUNDLE */`; if it does, run `cd originGUI && pnpm build` first +5. **No remote code on `chrome/packaged-runtime`** — the Chrome build must never fetch-and-run JavaScript, use `onreset`, `eval`, or `new Function`. Hooks live in `extension/lib/runtime/`; the menu is packaged via `extension/contents/menu.ts`. Master keeps the P-NP `onreset` pipeline for Edge/Firefox. +6. **Graceful degradation** — a hook target that stops resolving logs `[Origin] hook target missing: `; the other hooks keep working. A missing target means a Chrome Web Store resubmission. +7. **Prodigy's CSP stays intact** — the Chrome build does not strip it, so anything the menu or DNR loads (images, fonts, fetches) must come from `*.prodigygame.com` or be packaged and web-accessible. +8. **Dev bundle guard** — before committing `originGUI/dist/bundle.js`, confirm it does NOT end with `/* DEV BUNDLE */`; if it does, run `cd originGUI && pnpm build` first ## Branding (Play Origin / Prodigy Origin) diff --git a/docs/superpowers/specs/2026-09-24-chrome-packaged-runtime-design.md b/docs/superpowers/specs/2026-09-24-chrome-packaged-runtime-design.md index 83be789..0ed1357 100644 --- a/docs/superpowers/specs/2026-09-24-chrome-packaged-runtime-design.md +++ b/docs/superpowers/specs/2026-09-24-chrome-packaged-runtime-design.md @@ -48,9 +48,11 @@ Registry keys are prefab serialization names, so minification can't rename them. ## Removed from the Chrome extension -`background.ts` patch pipeline (the service worker keeps only the DNR image redirects), `contents/prodigy.ts`, `contents/origin-bridge.ts`, `lib/{bundle-cache,manifest,patches,patch-urls}.ts` and their tests, DNR rules 1 (block `game.min.js`) and 2 (strip CSP/XFO; MAIN-world content scripts aren't subject to page CSP), the `raw.githubusercontent.com` host permission, the popup's manifest/menu URL overrides, and the `unlimitedStorage` permission. +`background.ts` patch pipeline (the service worker keeps only the DNR image redirects), `contents/prodigy.ts`, `contents/origin-bridge.ts`, `lib/{bundle-cache,manifest,patches,patch-urls}.ts` and their tests, DNR rules 1 (block `game.min.js`) and 2 (strip CSP/XFO), the `raw.githubusercontent.com` host permission, the popup's manifest/menu URL overrides, and the `unlimitedStorage` permission. -The image redirects to GitHub-hosted PNGs stay. They're images, not code. +The image redirects stay, but point at packaged PNGs (`extensionPath`, web-accessible). They're images, not code. + +**Amendment (live checkpoint B):** MAIN-world scripts *execute* regardless of the page CSP, but their network loads don't get that exemption. With the CSP strip gone, Prodigy's CSP blocked the GitHub-hosted logo redirect (`img-src`), the menu's `statusmessage.json` (`connect-src`), its Google Fonts, and the Teleport zone art. Resolution: keep Prodigy's CSP intact. Serve the login art from the package via `extensionPath` (verified live), drop the status message, and label zone tiles by name. Fonts fall back to system sans-serif. ## Testing diff --git a/extension/lib/bundle-cache.ts b/extension/lib/bundle-cache.ts deleted file mode 100644 index 2882c58..0000000 --- a/extension/lib/bundle-cache.ts +++ /dev/null @@ -1,45 +0,0 @@ -export const CACHE_KEY = "patchedBundleCache" - -export type CacheEntry = { - gameClientVersion: string - manifestHash: string - patchedBundle: string - storedAt: number -} - -export type StorageLocalApi = { - get: (keys: string | string[]) => Promise> - set: (items: Record) => Promise - remove: (keys: string | string[]) => Promise -} - -export const getCachedBundle = async ( - storage: StorageLocalApi -): Promise => { - const result = await storage.get(CACHE_KEY) - const v = result[CACHE_KEY] - if (!v || typeof v !== "object") return undefined - const e = v as Partial - if ( - typeof e.gameClientVersion !== "string" || - typeof e.manifestHash !== "string" || - typeof e.patchedBundle !== "string" || - typeof e.storedAt !== "number" - ) { - return undefined - } - return e as CacheEntry -} - -export const setCachedBundle = async ( - storage: StorageLocalApi, - entry: CacheEntry -): Promise => { - await storage.set({ [CACHE_KEY]: entry }) -} - -export const clearCachedBundle = async ( - storage: StorageLocalApi -): Promise => { - await storage.remove(CACHE_KEY) -} diff --git a/extension/lib/manifest.ts b/extension/lib/manifest.ts deleted file mode 100644 index 973a3ef..0000000 --- a/extension/lib/manifest.ts +++ /dev/null @@ -1,53 +0,0 @@ -import type { PatchRule } from "./patches" - -export type Manifest = { - schemaVersion: 1 - patcherVersion: string - hash: string - rules: PatchRule[] - prefix: string - suffix: string - defaultMenuUrl: string -} - -const isPatchRule = (v: unknown): v is PatchRule => { - if (!v || typeof v !== "object") return false - const r = v as Record - return ( - typeof r.id === "string" && - typeof r.description === "string" && - typeof r.find === "string" && - typeof r.flags === "string" && - typeof r.replace === "string" && - typeof r.minMatches === "number" - ) -} - -export const validateManifest = (value: unknown): Manifest => { - if (!value || typeof value !== "object") { - throw new Error("manifest.json must be a JSON object") - } - const m = value as Record - if (m.schemaVersion !== 1) { - throw new Error(`manifest.schemaVersion must be 1 (got ${m.schemaVersion as unknown as string})`) - } - if (typeof m.patcherVersion !== "string") { - throw new Error("manifest.patcherVersion must be a string") - } - if (typeof m.hash !== "string") { - throw new Error("manifest.hash must be a string") - } - if (!Array.isArray(m.rules) || !m.rules.every(isPatchRule)) { - throw new Error("manifest.rules must be an array of PatchRule") - } - if (typeof m.prefix !== "string") { - throw new Error("manifest.prefix must be a string") - } - if (typeof m.suffix !== "string") { - throw new Error("manifest.suffix must be a string") - } - if (typeof m.defaultMenuUrl !== "string") { - throw new Error("manifest.defaultMenuUrl must be a string") - } - return m as unknown as Manifest -} diff --git a/extension/lib/patch-urls.ts b/extension/lib/patch-urls.ts deleted file mode 100644 index e5f2c54..0000000 --- a/extension/lib/patch-urls.ts +++ /dev/null @@ -1,18 +0,0 @@ -export const MANIFEST_URL = - "https://raw.githubusercontent.com/ProdigyPXP/P-NP/master/dist/manifest.json" - -// Matches canonical Prodigy game URL: //code.prodigygame.com/code//game.min.js -// Optional query string follows. -export const GAME_SCRIPT_RE = - /\/\/code\.prodigygame\.com\/code\/([^/]+)\/game\.min\.js(?:\?|#|$)/i - -export const isGameScriptSrc = (src: string | null | undefined): boolean => { - if (!src) return false - return GAME_SCRIPT_RE.test(src) -} - -export const gameVersionFromUrl = (url: string): string => { - if (!url) return "" - const m = url.match(GAME_SCRIPT_RE) - return m?.[1] ?? "" -} diff --git a/extension/lib/patches.ts b/extension/lib/patches.ts deleted file mode 100644 index 4e9743a..0000000 --- a/extension/lib/patches.ts +++ /dev/null @@ -1,42 +0,0 @@ -export type PatchRule = { - id: string - description: string - find: string - flags: string - replace: string - minMatches: number -} - -export type ApplyPatchRulesOutcome = { - output: string - perRuleCounts: Record -} - -export const applyPatchRules = ( - source: string, - rules: ReadonlyArray -): ApplyPatchRulesOutcome => { - const perRuleCounts: Record = {} - let output = source - for (const rule of rules) { - const re = new RegExp(rule.find, rule.flags) - let count = 0 - output = output.replace(re, (...args) => { - count += 1 - const groups = args.slice(1, -2) - let result = rule.replace - groups.forEach((g, i) => { - result = result.replace(new RegExp("\\$" + (i + 1), "g"), g ?? "") - }) - return result - }) - perRuleCounts[rule.id] = count - } - return { output, perRuleCounts } -} - -export const wrapWithPrefixSuffix = ( - body: string, - prefix: string, - suffix: string -): string => `${prefix}\n${body}\n${suffix}` diff --git a/extension/package.json b/extension/package.json index cb054ea..bfd321a 100644 --- a/extension/package.json +++ b/extension/package.json @@ -34,9 +34,7 @@ "description": "The ultimate open-source mod loader for online math games.", "author": "ProdigyPXP", "permissions": [ - "declarativeNetRequest", - "storage", - "unlimitedStorage" + "declarativeNetRequest" ], "web_accessible_resources": [ { @@ -45,8 +43,7 @@ } ], "host_permissions": [ - "*://*.prodigygame.com/*", - "https://raw.githubusercontent.com/*" + "*://*.prodigygame.com/*" ], "browser_specific_settings": { "gecko": { diff --git a/extension/popup.tsx b/extension/popup.tsx index 32c24ef..ab3df45 100644 --- a/extension/popup.tsx +++ b/extension/popup.tsx @@ -1,43 +1,10 @@ -import { useEffect, useState } from "react"; import { VERSION } from "./lib/version"; -import { motion, AnimatePresence } from "framer-motion"; -import { ExternalLink, Save, RotateCcw, Play, MessageCircle, ChevronDown } from "lucide-react"; +import { ExternalLink, Play, MessageCircle } from "lucide-react"; import { Button } from "./components/Button"; import logoUrl from "data-base64:./assets/icon.png"; import "./style.css"; function Popup() { - const [manifestUrl, setManifestUrl] = useState(""); - const [guiUrl, setGuiUrl] = useState(""); - const [saved, setSaved] = useState(false); - const [devOpen, setDevOpen] = useState(false); - const [devUnlocked, setDevUnlocked] = useState(false); - const [challengeInput, setChallengeInput] = useState(""); - - useEffect(() => { - chrome.storage.local.get(["originManifestUrl", "originGuiUrl"], (res) => { - setManifestUrl(res.originManifestUrl ?? ""); - setGuiUrl(res.originGuiUrl ?? ""); - }); - }, []); - - const handleSave = () => { - chrome.storage.local.set( - { originManifestUrl: manifestUrl, originGuiUrl: guiUrl }, - () => { - setSaved(true); - setTimeout(() => setSaved(false), 2000); - } - ); - }; - - const handleReset = () => { - chrome.storage.local.remove(["originManifestUrl", "originGuiUrl"], () => { - setManifestUrl(""); - setGuiUrl(""); - }); - }; - return (
      @@ -73,138 +40,6 @@ function Popup() {
      - -
      - - {/* Developer Options accordion */} - - - - {devOpen && ( - -
      -

      - ⚠️ Do not change these unless you know what you're doing. -

      - - {devUnlocked ? ( - <> - - - - -
      - - -
      - -

      - Leave blank to use defaults. Reload the Prodigy tab after saving. -

      - - ) : ( -
      - {(() => { - const checkAnswer = () => { - const answer = challengeInput.trim().toLowerCase(); - if (["i++", "i++;", "i += 1", "i += 1;"].includes(answer)) { - setDevUnlocked(true); - } - }; - return ( - <> - - setChallengeInput(e.target.value)} - onKeyDown={(e) => { - if (e.key === "Enter") { - checkAnswer(); - } - }} - className="field-input" - /> - - - ); - })()} -
      - )} -
      -
      - )} -
      ); } diff --git a/extension/tests/bundle-cache.test.ts b/extension/tests/bundle-cache.test.ts deleted file mode 100644 index 316a56d..0000000 --- a/extension/tests/bundle-cache.test.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { describe, it } from "node:test"; -import assert from "node:assert/strict"; -import { - CACHE_KEY, - getCachedBundle, - setCachedBundle, - clearCachedBundle, - type StorageLocalApi, - type CacheEntry -} from "../lib/bundle-cache.ts"; - -const makeFakeStorage = (initial: Record = {}): StorageLocalApi => { - let store: Record = { ...initial }; - return { - get: async (keys) => { - if (typeof keys === "string") return { [keys]: store[keys] }; - if (Array.isArray(keys)) { - const out: Record = {}; - for (const k of keys) out[k] = store[k]; - return out; - } - return { ...store }; - }, - set: async (items) => { store = { ...store, ...items }; }, - remove: async (keys) => { - const ks = Array.isArray(keys) ? keys : [keys]; - for (const k of ks) delete store[k]; - } - }; -}; - -const entry: CacheEntry = { - gameClientVersion: "2026.18.1", - manifestHash: "deadbeef00000000", - patchedBundle: "console.log(1)", - storedAt: 1000 -}; - -describe("getCachedBundle", () => { - it("returns undefined when nothing stored", async () => { - const r = await getCachedBundle(makeFakeStorage()); - assert.equal(r, undefined); - }); - - it("returns the stored entry", async () => { - const r = await getCachedBundle(makeFakeStorage({ [CACHE_KEY]: entry })); - assert.deepEqual(r, entry); - }); - - it("returns undefined when stored shape is invalid", async () => { - const r = await getCachedBundle(makeFakeStorage({ [CACHE_KEY]: { wrong: true } })); - assert.equal(r, undefined); - }); -}); - -describe("setCachedBundle", () => { - it("writes the entry", async () => { - const s = makeFakeStorage(); - await setCachedBundle(s, entry); - assert.deepEqual(await getCachedBundle(s), entry); - }); - - it("overwrites prior entries", async () => { - const s = makeFakeStorage(); - await setCachedBundle(s, entry); - await setCachedBundle(s, { ...entry, gameClientVersion: "2026.19.0" }); - const got = await getCachedBundle(s); - assert.equal(got?.gameClientVersion, "2026.19.0"); - }); -}); - -describe("clearCachedBundle", () => { - it("removes the entry", async () => { - const s = makeFakeStorage({ [CACHE_KEY]: entry }); - await clearCachedBundle(s); - assert.equal(await getCachedBundle(s), undefined); - }); - - it("no-ops when nothing is stored", async () => { - await clearCachedBundle(makeFakeStorage()); - }); -}); diff --git a/extension/tests/integration.test.ts b/extension/tests/integration.test.ts deleted file mode 100644 index 8b1f78c..0000000 --- a/extension/tests/integration.test.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { describe, it, test } from "node:test" -import assert from "node:assert/strict" -import { applyPatchRules, wrapWithPrefixSuffix, type PatchRule } from "../lib/patches.ts" -import { validateManifest } from "../lib/manifest.ts" - -const SYNTHETIC_MANIFEST = { - schemaVersion: 1, - patcherVersion: "4.4.0", - hash: "abc123def4567890", - prefix: "/* PRE */", - suffix: "/* POST */", - defaultMenuUrl: "https://example.com/bundle.js", - rules: [ - { - id: "singleton-exposure", - description: "", - find: "(_instance=this\\),this\\._game=([A-Za-z_$][\\w$]*)\\}destroy\\(\\)\\{)", - flags: "", - replace: "_instance=this),window.__PNP__=this,this._game=$2}destroy(){", - minMatches: 1 - }, - { - id: "safe-bind", - description: "", - find: "([A-Za-z_$][\\w$]*\\.q\\.instance\\.prodigy\\.gameContainer)\\.bind\\(", - flags: "g", - replace: "window.__pnp_safeBind($1,", - minMatches: 1 - } - ] as PatchRule[] -} - -const ORIGINAL = ` -class Prodigy{constructor(E){_instance=this),this._game=E}destroy(){}} -class X{thing(){return A.q.instance.prodigy.gameContainer.bind("MathTower");}} -class Y{other(){return B.q.instance.prodigy.gameContainer.bind("Other");}} -` - -describe("end-to-end: validateManifest → applyPatchRules → wrapWithPrefixSuffix", () => { - it("produces a wrapped bundle with prefix, patched core, and suffix", () => { - const manifest = validateManifest(SYNTHETIC_MANIFEST) - const { output: patched, perRuleCounts } = applyPatchRules(ORIGINAL, manifest.rules) - - assert.equal(perRuleCounts["singleton-exposure"], 1) - assert.equal(perRuleCounts["safe-bind"], 2) - assert.ok(patched.includes("window.__PNP__=this")) - assert.ok(patched.includes("window.__pnp_safeBind(A.q.instance.prodigy.gameContainer,")) - assert.ok(patched.includes("window.__pnp_safeBind(B.q.instance.prodigy.gameContainer,")) - - const wrapped = wrapWithPrefixSuffix(patched, manifest.prefix, manifest.suffix) - assert.ok(wrapped.startsWith("/* PRE */")) - assert.ok(wrapped.endsWith("/* POST */\n") || wrapped.endsWith("/* POST */")) - assert.ok(wrapped.includes("window.__PNP__=this")) - }) - - it("validateManifest rejects a malformed payload", () => { - assert.throws(() => validateManifest({ ...SYNTHETIC_MANIFEST, schemaVersion: 99 })) - }) -}) - -test("menu-URL prefix is prepended to wrapped bundle", () => { - const wrapped = wrapWithPrefixSuffix("body", "prefix", "suffix"); - const menuUrl = "https://example.com/m.js"; - const finalBundle = - `globalThis.__ORIGIN_MENU_URL__=${JSON.stringify(menuUrl)};\n${wrapped}`; - assert.ok(finalBundle.startsWith( - `globalThis.__ORIGIN_MENU_URL__="https://example.com/m.js";\n` - )); - assert.ok(finalBundle.includes("prefix\nbody\nsuffix")); -}); - -test("override URL takes priority over manifest.defaultMenuUrl", () => { - const manifest = { defaultMenuUrl: "https://default.example/m.js" }; - const override = "https://custom.example/m.js"; - const resolved = override || manifest.defaultMenuUrl; - assert.equal(resolved, "https://custom.example/m.js"); - - const emptyOverride: string = ""; - const resolved2 = emptyOverride || manifest.defaultMenuUrl; - assert.equal(resolved2, "https://default.example/m.js"); -}); diff --git a/extension/tests/manifest.test.ts b/extension/tests/manifest.test.ts deleted file mode 100644 index 1d4c9d6..0000000 --- a/extension/tests/manifest.test.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { describe, it, test } from "node:test"; -import assert from "node:assert/strict"; -import { validateManifest, type Manifest } from "../lib/manifest.ts"; - -const VALID: Manifest = { - schemaVersion: 1, - patcherVersion: "4.4.0", - hash: "deadbeef00000000", - rules: [ - { id: "r1", description: "", find: "a", flags: "g", replace: "b", minMatches: 1 } - ], - prefix: "PRE", - suffix: "POST", - defaultMenuUrl: "https://example.com/bundle.js" -}; - -describe("validateManifest", () => { - it("returns the manifest unchanged on a valid object", () => { - assert.deepEqual(validateManifest(VALID), VALID); - }); - - it("throws on null / non-object input", () => { - assert.throws(() => validateManifest(null)); - assert.throws(() => validateManifest("not an object")); - assert.throws(() => validateManifest(123)); - }); - - it("throws when schemaVersion is missing or wrong", () => { - assert.throws(() => validateManifest({ ...VALID, schemaVersion: 2 })); - assert.throws(() => validateManifest({ ...VALID, schemaVersion: undefined })); - }); - - it("throws when rules is not an array", () => { - assert.throws(() => validateManifest({ ...VALID, rules: "nope" })); - }); - - it("throws when a rule is missing required fields", () => { - assert.throws(() => validateManifest({ - ...VALID, - rules: [{ id: "r1", find: "a" }] - })); - }); - - it("throws when hash is not a string", () => { - assert.throws(() => validateManifest({ ...VALID, hash: 123 })); - }); - - it("throws when prefix/suffix are not strings", () => { - assert.throws(() => validateManifest({ ...VALID, prefix: null })); - assert.throws(() => validateManifest({ ...VALID, suffix: null })); - }); -}); - -test("validateManifest accepts defaultMenuUrl", () => { - const ok = validateManifest({ - schemaVersion: 1, - patcherVersion: "4.4.1", - hash: "deadbeefcafebabe", - rules: [], - prefix: "P", - suffix: "S", - defaultMenuUrl: "https://example.com/bundle.js" - }); - assert.equal(ok.defaultMenuUrl, "https://example.com/bundle.js"); -}); - -test("validateManifest rejects manifest missing defaultMenuUrl", () => { - assert.throws(() => validateManifest({ - schemaVersion: 1, - patcherVersion: "4.4.1", - hash: "deadbeefcafebabe", - rules: [], - prefix: "P", - suffix: "S" - }), /defaultMenuUrl/); -}); - -test("validateManifest rejects non-string defaultMenuUrl", () => { - assert.throws(() => validateManifest({ - schemaVersion: 1, - patcherVersion: "4.4.1", - hash: "deadbeefcafebabe", - rules: [], - prefix: "P", - suffix: "S", - defaultMenuUrl: 42 - }), /defaultMenuUrl/); -}); diff --git a/extension/tests/patch-urls.test.ts b/extension/tests/patch-urls.test.ts deleted file mode 100644 index d0d489e..0000000 --- a/extension/tests/patch-urls.test.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { describe, it } from "node:test"; -import assert from "node:assert/strict"; -import { - MANIFEST_URL, - GAME_SCRIPT_RE, - isGameScriptSrc, - gameVersionFromUrl -} from "../lib/patch-urls.ts"; - -describe("MANIFEST_URL", () => { - it("points at raw.githubusercontent.com on the master branch", () => { - assert.equal( - MANIFEST_URL, - "https://raw.githubusercontent.com/ProdigyPXP/P-NP/master/dist/manifest.json" - ); - }); - - it("uses https", () => { - assert.ok(MANIFEST_URL.startsWith("https://")); - }); -}); - -describe("GAME_SCRIPT_RE", () => { - it("matches the canonical code.prodigygame.com game URL with version path", () => { - assert.ok(GAME_SCRIPT_RE.test("https://code.prodigygame.com/code/2026.18.1/game.min.js")); - }); - - it("matches with a ?v= query string", () => { - assert.ok(GAME_SCRIPT_RE.test("https://code.prodigygame.com/code/2026.18.1/game.min.js?v=2026.18.1")); - }); - - it("does not match unrelated scripts", () => { - assert.ok(!GAME_SCRIPT_RE.test("https://code.prodigygame.com/js/load-game-abc.min.js")); - assert.ok(!GAME_SCRIPT_RE.test("https://example.com/game.min.js")); - }); -}); - -describe("isGameScriptSrc", () => { - it("returns true for the canonical URL", () => { - assert.equal( - isGameScriptSrc("https://code.prodigygame.com/code/2026.18.1/game.min.js"), - true - ); - }); - - it("returns false for empty / null / undefined", () => { - assert.equal(isGameScriptSrc(""), false); - assert.equal(isGameScriptSrc(null as unknown as string), false); - assert.equal(isGameScriptSrc(undefined), false); - }); -}); - -describe("gameVersionFromUrl", () => { - it("extracts the version segment from the URL path", () => { - assert.equal( - gameVersionFromUrl("https://code.prodigygame.com/code/2026.18.1/game.min.js?v=2026.18.1"), - "2026.18.1" - ); - }); - - it("extracts even when no query string", () => { - assert.equal( - gameVersionFromUrl("https://code.prodigygame.com/code/2026.25.0/game.min.js"), - "2026.25.0" - ); - }); - - it("returns empty string when path doesn't match", () => { - assert.equal(gameVersionFromUrl("https://example.com/foo.js"), ""); - assert.equal(gameVersionFromUrl(""), ""); - }); -}); diff --git a/extension/tests/patches.test.ts b/extension/tests/patches.test.ts deleted file mode 100644 index fd8fac9..0000000 --- a/extension/tests/patches.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { describe, it } from "node:test"; -import assert from "node:assert/strict"; -import { applyPatchRules, wrapWithPrefixSuffix, type PatchRule } from "../lib/patches.ts"; - -const singletonRule: PatchRule = { - id: "singleton-exposure", - description: "", - find: "(_instance=this\\),this\\._game=([A-Za-z_$][\\w$]*)\\}destroy\\(\\)\\{)", - flags: "", - replace: "_instance=this),window.__PNP__=this,this._game=$2}destroy(){", - minMatches: 1 -}; - -const safeBindRule: PatchRule = { - id: "safe-bind", - description: "", - find: "([A-Za-z_$][\\w$]*\\.q\\.instance\\.prodigy\\.gameContainer)\\.bind\\(", - flags: "g", - replace: "window.__pnp_safeBind($1,", - minMatches: 1 -}; - -describe("applyPatchRules", () => { - it("applies a rule with first-match semantics (no g flag)", () => { - const input = `class X{constructor(){_instance=this),this._game=E}destroy(){}}`; - const { output, perRuleCounts } = applyPatchRules(input, [singletonRule]); - assert.equal(perRuleCounts["singleton-exposure"], 1); - assert.ok(output.includes("window.__PNP__=this")); - }); - - it("applies a rule with all-match semantics (g flag)", () => { - const input = `A.q.instance.prodigy.gameContainer.bind("a"); B.q.instance.prodigy.gameContainer.bind("b");`; - const { output, perRuleCounts } = applyPatchRules(input, [safeBindRule]); - assert.equal(perRuleCounts["safe-bind"], 2); - assert.ok(output.includes("window.__pnp_safeBind(A.q.instance.prodigy.gameContainer,")); - assert.ok(output.includes("window.__pnp_safeBind(B.q.instance.prodigy.gameContainer,")); - }); - - it("applies rules in order", () => { - const a: PatchRule = { id: "a", description: "", find: "foo", flags: "g", replace: "FOO", minMatches: 1 }; - const b: PatchRule = { id: "b", description: "", find: "FOO", flags: "g", replace: "BAR", minMatches: 1 }; - const { output } = applyPatchRules("foo", [a, b]); - assert.equal(output, "BAR"); - }); - - it("reports zero matches without throwing", () => { - const { output, perRuleCounts } = applyPatchRules("nothing", [singletonRule]); - assert.equal(perRuleCounts["singleton-exposure"], 0); - assert.equal(output, "nothing"); - }); -}); - -describe("wrapWithPrefixSuffix", () => { - it("prepends prefix and appends suffix", () => { - const out = wrapWithPrefixSuffix("BODY", "PRE", "POST"); - assert.equal(out, "PRE\nBODY\nPOST"); - }); - - it("preserves the body verbatim", () => { - const body = "(function(){var x=1;})();"; - const out = wrapWithPrefixSuffix(body, "P", "S"); - assert.ok(out.includes(body)); - }); -}); diff --git a/originGUI/dist/bundle.js b/originGUI/dist/bundle.js index 46e88b2..af8b6a4 100644 --- a/originGUI/dist/bundle.js +++ b/originGUI/dist/bundle.js @@ -175,7 +175,7 @@ z-index: 2; background-color: rgba(0, 0, 0, 0.5); backdrop-filter: blur(5px); -}`,t="origingui-styles",n=document.getElementById(t)||document.createElement("style");n.id=t,n.textContent=e,n.parentNode||document.head.appendChild(n)})();var c=window._,r=c.player,Ct=()=>{try{return window._.instance?.game?.state?.getCurrentState()??null}catch{return null}},he=new Proxy({},{get(e,t){let n=Ct();return n?n[t]:void 0},set(e,t,n){let o=Ct();return o&&(o[t]=n),!0}}),xt=c.instance,Ae=xt.game,V=xt.prodigy,Ls=c.instance.game.state.states.get("Boot").gameData,Ie=(e,t)=>c.gameData[e].find(n=>n.ID===t)??null,P=9e9,$=()=>{c.network.processPlayer=!0,c.player.forceSaveCharacter()},qn="https://raw.githubusercontent.com/ProdigyPXP/ProdigyOrigin/master/originGUI/src/assets/",T=e=>`${qn}${e}`,Ms={academy:T("academy.png"),bonfire_spire:T("bonfire_spire.png"),forest:T("forest.png"),shipwreck_shore:T("shipwreck_shore.png"),shiverchill:T("shiverchill.png"),skywatch:T("skywatch.png"),dyno:T("dyno.png"),elemental_guardian:T("elemental_guardian.png"),darktower:T("darktower.png"),earthtower:T("earthtower.png"),crystal_caverns:T("crystal_caverns.png"),archives:T("archives.png"),house:T("house.png"),toyzone:T("toyzone.png"),tower_town:T("tower_town.png"),lamplight:T("lamplight.png")};function Ht(e,t,n){if(typeof e=="function"?e===t:e.has(t))return arguments.length<3?t:n;throw new TypeError("Private element is not present on this object")}function Fn(e,t){if(t.has(e))throw new TypeError("Cannot initialize the same private elements twice on an object")}function Et(e,t){return e.get(Ht(e,t))}function jn(e,t,n){Fn(e,t),t.set(e,n)}function Wn(e,t,n){return e.set(Ht(e,t),n),n}var Yn=100,w={},Vn=()=>{w.previousActiveElement instanceof HTMLElement?(w.previousActiveElement.focus(),w.previousActiveElement=null):document.body&&document.body.focus()},Un=e=>new Promise(t=>{if(!e)return t();let n=window.scrollX,o=window.scrollY;w.restoreFocusTimeout=setTimeout(()=>{Vn(),t()},Yn),window.scrollTo(n,o)}),_t="swal2-",Gn=["container","shown","height-auto","iosfix","popup","modal","no-backdrop","no-transition","toast","toast-shown","show","hide","close","title","html-container","actions","confirm","deny","cancel","default-outline","footer","icon","icon-content","image","input","file","range","select","radio","checkbox","label","textarea","inputerror","input-label","validation-message","progress-steps","active-progress-step","progress-step","progress-step-line","loader","loading","styled","top","top-start","top-end","top-left","top-right","center","center-start","center-end","center-left","center-right","bottom","bottom-start","bottom-end","bottom-left","bottom-right","grow-row","grow-column","grow-fullscreen","rtl","timer-progress-bar","timer-progress-bar-container","scrollbar-measure","icon-success","icon-warning","icon-info","icon-question","icon-error","draggable","dragging"],i=Gn.reduce((e,t)=>(e[t]=_t+t,e),{}),Kn=["success","warning","info","question","error"],De=Kn.reduce((e,t)=>(e[t]=_t+t,e),{}),Nt="SweetAlert2:",nt=e=>e.charAt(0).toUpperCase()+e.slice(1),B=e=>{console.warn(`${Nt} ${typeof e=="object"?e.join(" "):e}`)},ee=e=>{console.error(`${Nt} ${e}`)},St=[],Xn=e=>{St.includes(e)||(St.push(e),B(e))},Rt=function(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:null;Xn(`"${e}" is deprecated and will be removed in the next major release.${t?` Use "${t}" instead.`:""}`)},Re=e=>typeof e=="function"?e():e,ot=e=>e&&typeof e.toPromise=="function",ye=e=>ot(e)?e.toPromise():Promise.resolve(e),rt=e=>e&&Promise.resolve(e)===e,L=()=>document.body.querySelector(`.${i.container}`),be=e=>{let t=L();return t?t.querySelector(e):null},H=e=>be(`.${e}`),y=()=>H(i.popup),ae=()=>H(i.icon),Zn=()=>H(i["icon-content"]),zt=()=>H(i.title),st=()=>H(i["html-container"]),qt=()=>H(i.image),at=()=>H(i["progress-steps"]),ze=()=>H(i["validation-message"]),z=()=>be(`.${i.actions} .${i.confirm}`),ie=()=>be(`.${i.actions} .${i.cancel}`),te=()=>be(`.${i.actions} .${i.deny}`),Jn=()=>H(i["input-label"]),le=()=>be(`.${i.loader}`),ve=()=>H(i.actions),Ft=()=>H(i.footer),qe=()=>H(i["timer-progress-bar"]),it=()=>H(i.close),Qn=` +}`,t="origingui-styles",n=document.getElementById(t)||document.createElement("style");n.id=t,n.textContent=e,n.parentNode||document.head.appendChild(n)})();var c=window._,r=c.player,kt=()=>{try{return window._.instance?.game?.state?.getCurrentState()??null}catch{return null}},ge=new Proxy({},{get(e,t){let n=kt();return n?n[t]:void 0},set(e,t,n){let o=kt();return o&&(o[t]=n),!0}}),Ct=c.instance,Pe=Ct.game,Y=Ct.prodigy,Ds=c.instance.game.state.states.get("Boot").gameData,Ae=(e,t)=>c.gameData[e].find(n=>n.ID===t)??null,P=9e9,M=()=>{c.network.processPlayer=!0,c.player.forceSaveCharacter()};function Ot(e,t,n){if(typeof e=="function"?e===t:e.has(t))return arguments.length<3?t:n;throw new TypeError("Private element is not present on this object")}function zn(e,t){if(t.has(e))throw new TypeError("Cannot initialize the same private elements twice on an object")}function xt(e,t){return e.get(Ot(e,t))}function qn(e,t,n){zn(e,t),t.set(e,n)}function Fn(e,t,n){return e.set(Ot(e,t),n),n}var jn=100,w={},Wn=()=>{w.previousActiveElement instanceof HTMLElement?(w.previousActiveElement.focus(),w.previousActiveElement=null):document.body&&document.body.focus()},Yn=e=>new Promise(t=>{if(!e)return t();let n=window.scrollX,o=window.scrollY;w.restoreFocusTimeout=setTimeout(()=>{Wn(),t()},jn),window.scrollTo(n,o)}),Ht="swal2-",Vn=["container","shown","height-auto","iosfix","popup","modal","no-backdrop","no-transition","toast","toast-shown","show","hide","close","title","html-container","actions","confirm","deny","cancel","default-outline","footer","icon","icon-content","image","input","file","range","select","radio","checkbox","label","textarea","inputerror","input-label","validation-message","progress-steps","active-progress-step","progress-step","progress-step-line","loader","loading","styled","top","top-start","top-end","top-left","top-right","center","center-start","center-end","center-left","center-right","bottom","bottom-start","bottom-end","bottom-left","bottom-right","grow-row","grow-column","grow-fullscreen","rtl","timer-progress-bar","timer-progress-bar-container","scrollbar-measure","icon-success","icon-warning","icon-info","icon-question","icon-error","draggable","dragging"],i=Vn.reduce((e,t)=>(e[t]=Ht+t,e),{}),Un=["success","warning","info","question","error"],Te=Un.reduce((e,t)=>(e[t]=Ht+t,e),{}),_t="SweetAlert2:",tt=e=>e.charAt(0).toUpperCase()+e.slice(1),D=e=>{console.warn(`${_t} ${typeof e=="object"?e.join(" "):e}`)},Q=e=>{console.error(`${_t} ${e}`)},Et=[],Gn=e=>{Et.includes(e)||(Et.push(e),D(e))},Nt=function(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:null;Gn(`"${e}" is deprecated and will be removed in the next major release.${t?` Use "${t}" instead.`:""}`)},Ne=e=>typeof e=="function"?e():e,nt=e=>e&&typeof e.toPromise=="function",he=e=>nt(e)?e.toPromise():Promise.resolve(e),ot=e=>e&&Promise.resolve(e)===e,B=()=>document.body.querySelector(`.${i.container}`),ye=e=>{let t=B();return t?t.querySelector(e):null},O=e=>ye(`.${e}`),y=()=>O(i.popup),se=()=>O(i.icon),Kn=()=>O(i["icon-content"]),Rt=()=>O(i.title),rt=()=>O(i["html-container"]),zt=()=>O(i.image),st=()=>O(i["progress-steps"]),Re=()=>O(i["validation-message"]),R=()=>ye(`.${i.actions} .${i.confirm}`),ae=()=>ye(`.${i.actions} .${i.cancel}`),ee=()=>ye(`.${i.actions} .${i.deny}`),Xn=()=>O(i["input-label"]),ie=()=>ye(`.${i.loader}`),be=()=>O(i.actions),qt=()=>O(i.footer),ze=()=>O(i["timer-progress-bar"]),at=()=>O(i.close),Zn=` a[href], area[href], input:not([disabled]), @@ -190,7 +190,7 @@ audio[controls], video[controls], summary -`,lt=()=>{let e=y();if(!e)return[];let t=e.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])'),n=Array.from(t).sort((a,d)=>{let m=parseInt(a.getAttribute("tabindex")||"0"),f=parseInt(d.getAttribute("tabindex")||"0");return m>f?1:ma.getAttribute("tabindex")!=="-1");return[...new Set(n.concat(s))].filter(a=>M(a))},ct=()=>j(document.body,i.shown)&&!j(document.body,i["toast-shown"])&&!j(document.body,i["no-backdrop"]),Fe=()=>{let e=y();return e?j(e,i.toast):!1},eo=()=>{let e=y();return e?e.hasAttribute("data-loading"):!1},_=(e,t)=>{if(e.textContent="",t){let o=new DOMParser().parseFromString(t,"text/html"),s=o.querySelector("head");s&&Array.from(s.childNodes).forEach(d=>{e.appendChild(d)});let a=o.querySelector("body");a&&Array.from(a.childNodes).forEach(d=>{d instanceof HTMLVideoElement||d instanceof HTMLAudioElement?e.appendChild(d.cloneNode(!0)):e.appendChild(d)})}},j=(e,t)=>{if(!t)return!1;let n=t.split(/\s+/);for(let o=0;o{Array.from(e.classList).forEach(n=>{!Object.values(i).includes(n)&&!Object.values(De).includes(n)&&!Object.values(t.showClass||{}).includes(n)&&e.classList.remove(n)})},O=(e,t,n)=>{if(to(e,t),!t.customClass)return;let o=t.customClass[n];if(o){if(typeof o!="string"&&!o.forEach){B(`Invalid type of customClass.${n}! Expected string or iterable object, got "${typeof o}"`);return}h(e,o)}},je=(e,t)=>{if(!t)return null;switch(t){case"select":case"textarea":case"file":return e.querySelector(`.${i.popup} > .${i[t]}`);case"checkbox":return e.querySelector(`.${i.popup} > .${i.checkbox} input`);case"radio":return e.querySelector(`.${i.popup} > .${i.radio} input:checked`)||e.querySelector(`.${i.popup} > .${i.radio} input:first-child`);case"range":return e.querySelector(`.${i.popup} > .${i.range} input`);default:return e.querySelector(`.${i.popup} > .${i.input}`)}},jt=e=>{if(e.focus(),e.type!=="file"){let t=e.value;e.value="",e.value=t}},Wt=(e,t,n)=>{!e||!t||(typeof t=="string"&&(t=t.split(/\s+/).filter(Boolean)),t.forEach(o=>{Array.isArray(e)?e.forEach(s=>{n?s.classList.add(o):s.classList.remove(o)}):n?e.classList.add(o):e.classList.remove(o)}))},h=(e,t)=>{Wt(e,t,!0)},N=(e,t)=>{Wt(e,t,!1)},U=(e,t)=>{let n=Array.from(e.children);for(let o=0;o{n===`${parseInt(n)}`&&(n=parseInt(n)),n||parseInt(n)===0?e.style.setProperty(t,typeof n=="number"?`${n}px`:n):e.style.removeProperty(t)},A=function(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"flex";e&&(e.style.display=t)},D=e=>{e&&(e.style.display="none")},ut=function(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"block";e&&new MutationObserver(()=>{ke(e,e.innerHTML,t)}).observe(e,{childList:!0,subtree:!0})},Pt=(e,t,n,o)=>{let s=e.querySelector(t);s&&s.style.setProperty(n,o)},ke=function(e,t){let n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:"flex";t?A(e,n):D(e)},M=e=>!!(e&&(e.offsetWidth||e.offsetHeight||e.getClientRects().length)),no=()=>!M(z())&&!M(te())&&!M(ie()),At=e=>e.scrollHeight>e.clientHeight,Yt=e=>{let t=window.getComputedStyle(e),n=parseFloat(t.getPropertyValue("animation-duration")||"0"),o=parseFloat(t.getPropertyValue("transition-duration")||"0");return n>0||o>0},dt=function(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,n=qe();n&&M(n)&&(t&&(n.style.transition="none",n.style.width="100%"),setTimeout(()=>{n.style.transition=`width ${e/1e3}s linear`,n.style.width="0%"},10))},oo=()=>{let e=qe();if(!e)return;let t=parseInt(window.getComputedStyle(e).width);e.style.removeProperty("transition"),e.style.width="100%";let n=parseInt(window.getComputedStyle(e).width),o=t/n*100;e.style.width=`${o}%`},ro=()=>typeof window>"u"||typeof document>"u",so=` +`,it=()=>{let e=y();if(!e)return[];let t=e.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])'),n=Array.from(t).sort((a,d)=>{let p=parseInt(a.getAttribute("tabindex")||"0"),f=parseInt(d.getAttribute("tabindex")||"0");return p>f?1:pa.getAttribute("tabindex")!=="-1");return[...new Set(n.concat(s))].filter(a=>L(a))},lt=()=>F(document.body,i.shown)&&!F(document.body,i["toast-shown"])&&!F(document.body,i["no-backdrop"]),qe=()=>{let e=y();return e?F(e,i.toast):!1},Jn=()=>{let e=y();return e?e.hasAttribute("data-loading"):!1},H=(e,t)=>{if(e.textContent="",t){let o=new DOMParser().parseFromString(t,"text/html"),s=o.querySelector("head");s&&Array.from(s.childNodes).forEach(d=>{e.appendChild(d)});let a=o.querySelector("body");a&&Array.from(a.childNodes).forEach(d=>{d instanceof HTMLVideoElement||d instanceof HTMLAudioElement?e.appendChild(d.cloneNode(!0)):e.appendChild(d)})}},F=(e,t)=>{if(!t)return!1;let n=t.split(/\s+/);for(let o=0;o{Array.from(e.classList).forEach(n=>{!Object.values(i).includes(n)&&!Object.values(Te).includes(n)&&!Object.values(t.showClass||{}).includes(n)&&e.classList.remove(n)})},$=(e,t,n)=>{if(Qn(e,t),!t.customClass)return;let o=t.customClass[n];if(o){if(typeof o!="string"&&!o.forEach){D(`Invalid type of customClass.${n}! Expected string or iterable object, got "${typeof o}"`);return}h(e,o)}},Fe=(e,t)=>{if(!t)return null;switch(t){case"select":case"textarea":case"file":return e.querySelector(`.${i.popup} > .${i[t]}`);case"checkbox":return e.querySelector(`.${i.popup} > .${i.checkbox} input`);case"radio":return e.querySelector(`.${i.popup} > .${i.radio} input:checked`)||e.querySelector(`.${i.popup} > .${i.radio} input:first-child`);case"range":return e.querySelector(`.${i.popup} > .${i.range} input`);default:return e.querySelector(`.${i.popup} > .${i.input}`)}},Ft=e=>{if(e.focus(),e.type!=="file"){let t=e.value;e.value="",e.value=t}},jt=(e,t,n)=>{!e||!t||(typeof t=="string"&&(t=t.split(/\s+/).filter(Boolean)),t.forEach(o=>{Array.isArray(e)?e.forEach(s=>{n?s.classList.add(o):s.classList.remove(o)}):n?e.classList.add(o):e.classList.remove(o)}))},h=(e,t)=>{jt(e,t,!0)},_=(e,t)=>{jt(e,t,!1)},V=(e,t)=>{let n=Array.from(e.children);for(let o=0;o{n===`${parseInt(n)}`&&(n=parseInt(n)),n||parseInt(n)===0?e.style.setProperty(t,typeof n=="number"?`${n}px`:n):e.style.removeProperty(t)},A=function(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"flex";e&&(e.style.display=t)},T=e=>{e&&(e.style.display="none")},ct=function(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:"block";e&&new MutationObserver(()=>{ve(e,e.innerHTML,t)}).observe(e,{childList:!0,subtree:!0})},St=(e,t,n,o)=>{let s=e.querySelector(t);s&&s.style.setProperty(n,o)},ve=function(e,t){let n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:"flex";t?A(e,n):T(e)},L=e=>!!(e&&(e.offsetWidth||e.offsetHeight||e.getClientRects().length)),eo=()=>!L(R())&&!L(ee())&&!L(ae()),Pt=e=>e.scrollHeight>e.clientHeight,Wt=e=>{let t=window.getComputedStyle(e),n=parseFloat(t.getPropertyValue("animation-duration")||"0"),o=parseFloat(t.getPropertyValue("transition-duration")||"0");return n>0||o>0},ut=function(e){let t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,n=ze();n&&L(n)&&(t&&(n.style.transition="none",n.style.width="100%"),setTimeout(()=>{n.style.transition=`width ${e/1e3}s linear`,n.style.width="0%"},10))},to=()=>{let e=ze();if(!e)return;let t=parseInt(window.getComputedStyle(e).width);e.style.removeProperty("transition"),e.style.width="100%";let n=parseInt(window.getComputedStyle(e).width),o=t/n*100;e.style.width=`${o}%`},no=()=>typeof window>"u"||typeof document>"u",oo=`
        @@ -223,28 +223,28 @@
        -`.replace(/(^|\n)\s*/g,""),ao=()=>{let e=L();return e?(e.remove(),N([document.documentElement,document.body],[i["no-backdrop"],i["toast-shown"],i["has-column"]]),!0):!1},X=()=>{w.currentInstance.resetValidationMessage()},io=()=>{let e=y(),t=U(e,i.input),n=U(e,i.file),o=e.querySelector(`.${i.range} input`),s=e.querySelector(`.${i.range} output`),a=U(e,i.select),d=e.querySelector(`.${i.checkbox} input`),m=U(e,i.textarea);t.oninput=X,n.onchange=X,a.onchange=X,d.onchange=X,m.oninput=X,o.oninput=()=>{X(),s.value=o.value},o.onchange=()=>{X(),s.value=o.value}},lo=e=>typeof e=="string"?document.querySelector(e):e,co=e=>{let t=y();t.setAttribute("role",e.toast?"alert":"dialog"),t.setAttribute("aria-live",e.toast?"polite":"assertive"),e.toast||t.setAttribute("aria-modal","true")},uo=e=>{window.getComputedStyle(e).direction==="rtl"&&h(L(),i.rtl)},po=e=>{let t=ao();if(ro()){ee("SweetAlert2 requires document to initialize");return}let n=document.createElement("div");n.className=i.container,t&&h(n,i["no-transition"]),_(n,so),n.dataset.swal2Theme=e.theme;let o=lo(e.target);o.appendChild(n),co(e),uo(o),io()},pt=(e,t)=>{e instanceof HTMLElement?t.appendChild(e):typeof e=="object"?mo(e,t):e&&_(t,e)},mo=(e,t)=>{e.jquery?fo(t,e):_(t,e.toString())},fo=(e,t)=>{if(e.textContent="",0 in t)for(let n=0;n in t;n++)e.appendChild(t[n].cloneNode(!0));else e.appendChild(t.cloneNode(!0))},wo=(e,t)=>{let n=ve(),o=le();!n||!o||(!t.showConfirmButton&&!t.showDenyButton&&!t.showCancelButton?D(n):A(n),O(n,t,"actions"),go(n,o,t),_(o,t.loaderHtml||""),O(o,t,"loader"))};function go(e,t,n){let o=z(),s=te(),a=ie();!o||!s||!a||(Xe(o,"confirm",n),Xe(s,"deny",n),Xe(a,"cancel",n),ho(o,s,a,n),n.reverseButtons&&(n.toast?(e.insertBefore(a,o),e.insertBefore(s,o)):(e.insertBefore(a,t),e.insertBefore(s,t),e.insertBefore(o,t))))}function ho(e,t,n,o){if(!o.buttonsStyling){N([e,t,n],i.styled);return}h([e,t,n],i.styled),o.confirmButtonColor&&(e.style.backgroundColor=o.confirmButtonColor,h(e,i["default-outline"])),o.denyButtonColor&&(t.style.backgroundColor=o.denyButtonColor,h(t,i["default-outline"])),o.cancelButtonColor&&(n.style.backgroundColor=o.cancelButtonColor,h(n,i["default-outline"]))}function Xe(e,t,n){let o=nt(t);ke(e,n[`show${o}Button`],"inline-block"),_(e,n[`${t}ButtonText`]||""),e.setAttribute("aria-label",n[`${t}ButtonAriaLabel`]||""),e.className=i[t],O(e,n,`${t}Button`)}var yo=(e,t)=>{let n=it();n&&(_(n,t.closeButtonHtml||""),O(n,t,"closeButton"),ke(n,t.showCloseButton),n.setAttribute("aria-label",t.closeButtonAriaLabel||""))},bo=(e,t)=>{let n=L();n&&(vo(n,t.backdrop),ko(n,t.position),Co(n,t.grow),O(n,t,"container"))};function vo(e,t){typeof t=="string"?e.style.background=t:t||h([document.documentElement,document.body],i["no-backdrop"])}function ko(e,t){t&&(t in i?h(e,i[t]):(B('The "position" parameter is not valid, defaulting to "center"'),h(e,i.center)))}function Co(e,t){t&&h(e,i[`grow-${t}`])}var v={innerParams:new WeakMap,domCache:new WeakMap},xo=["input","file","range","select","radio","checkbox","textarea"],Eo=(e,t)=>{let n=y();if(!n)return;let o=v.innerParams.get(e),s=!o||t.input!==o.input;xo.forEach(a=>{let d=U(n,i[a]);d&&(Ao(a,t.inputAttributes),d.className=i[a],s&&D(d))}),t.input&&(s&&So(t),Io(t))},So=e=>{if(!e.input)return;if(!S[e.input]){ee(`Unexpected type of input! Expected ${Object.keys(S).join(" | ")}, got "${e.input}"`);return}let t=Vt(e.input);if(!t)return;let n=S[e.input](t,e);A(t),e.inputAutoFocus&&setTimeout(()=>{jt(n)})},Po=e=>{for(let t=0;t{let n=y();if(!n)return;let o=je(n,e);if(o){Po(o);for(let s in t)o.setAttribute(s,t[s])}},Io=e=>{if(!e.input)return;let t=Vt(e.input);t&&O(t,e,"input")},mt=(e,t)=>{!e.placeholder&&t.inputPlaceholder&&(e.placeholder=t.inputPlaceholder)},Ce=(e,t,n)=>{if(n.inputLabel){let o=document.createElement("label"),s=i["input-label"];o.setAttribute("for",e.id),o.className=s,typeof n.customClass=="object"&&h(o,n.customClass.inputLabel),o.innerText=n.inputLabel,t.insertAdjacentElement("beforebegin",o)}},Vt=e=>{let t=y();if(t)return U(t,i[e]||i.input)},Be=(e,t)=>{["string","number"].includes(typeof t)?e.value=`${t}`:rt(t)||B(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof t}"`)},S={};S.text=S.email=S.password=S.number=S.tel=S.url=S.search=S.date=S["datetime-local"]=S.time=S.week=S.month=(e,t)=>(Be(e,t.inputValue),Ce(e,e,t),mt(e,t),e.type=t.input,e);S.file=(e,t)=>(Ce(e,e,t),mt(e,t),e);S.range=(e,t)=>{let n=e.querySelector("input"),o=e.querySelector("output");return Be(n,t.inputValue),n.type=t.input,Be(o,t.inputValue),Ce(n,e,t),e};S.select=(e,t)=>{if(e.textContent="",t.inputPlaceholder){let n=document.createElement("option");_(n,t.inputPlaceholder),n.value="",n.disabled=!0,n.selected=!0,e.appendChild(n)}return Ce(e,e,t),e};S.radio=e=>(e.textContent="",e);S.checkbox=(e,t)=>{let n=je(y(),"checkbox");n.value="1",n.checked=!!t.inputValue;let o=e.querySelector("span");return _(o,t.inputPlaceholder||t.inputLabel),n};S.textarea=(e,t)=>{Be(e,t.inputValue),mt(e,t),Ce(e,e,t);let n=o=>parseInt(window.getComputedStyle(o).marginLeft)+parseInt(window.getComputedStyle(o).marginRight);return setTimeout(()=>{if("MutationObserver"in window){let o=parseInt(window.getComputedStyle(y()).width),s=()=>{if(!document.body.contains(e))return;let a=e.offsetWidth+n(e);a>o?y().style.width=`${a}px`:Z(y(),"width",t.width)};new MutationObserver(s).observe(e,{attributes:!0,attributeFilter:["style"]})}}),e};var To=(e,t)=>{let n=st();n&&(ut(n),O(n,t,"htmlContainer"),t.html?(pt(t.html,n),A(n,"block")):t.text?(n.textContent=t.text,A(n,"block")):D(n),Eo(e,t))},Do=(e,t)=>{let n=Ft();n&&(ut(n),ke(n,t.footer,"block"),t.footer&&pt(t.footer,n),O(n,t,"footer"))},Bo=(e,t)=>{let n=v.innerParams.get(e),o=ae();if(!o)return;if(n&&t.icon===n.icon){Tt(o,t),It(o,t);return}if(!t.icon&&!t.iconHtml){D(o);return}if(t.icon&&Object.keys(De).indexOf(t.icon)===-1){ee(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${t.icon}"`),D(o);return}A(o),Tt(o,t),It(o,t),h(o,t.showClass&&t.showClass.icon),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",Ut)},It=(e,t)=>{for(let[n,o]of Object.entries(De))t.icon!==n&&N(e,o);h(e,t.icon&&De[t.icon]),$o(e,t),Ut(),O(e,t,"icon")},Ut=()=>{let e=y();if(!e)return;let t=window.getComputedStyle(e).getPropertyValue("background-color"),n=e.querySelectorAll("[class^=swal2-success-circular-line], .swal2-success-fix");for(let o=0;o{let e=B();return e?(e.remove(),_([document.documentElement,document.body],[i["no-backdrop"],i["toast-shown"],i["has-column"]]),!0):!1},K=()=>{w.currentInstance.resetValidationMessage()},so=()=>{let e=y(),t=V(e,i.input),n=V(e,i.file),o=e.querySelector(`.${i.range} input`),s=e.querySelector(`.${i.range} output`),a=V(e,i.select),d=e.querySelector(`.${i.checkbox} input`),p=V(e,i.textarea);t.oninput=K,n.onchange=K,a.onchange=K,d.onchange=K,p.oninput=K,o.oninput=()=>{K(),s.value=o.value},o.onchange=()=>{K(),s.value=o.value}},ao=e=>typeof e=="string"?document.querySelector(e):e,io=e=>{let t=y();t.setAttribute("role",e.toast?"alert":"dialog"),t.setAttribute("aria-live",e.toast?"polite":"assertive"),e.toast||t.setAttribute("aria-modal","true")},lo=e=>{window.getComputedStyle(e).direction==="rtl"&&h(B(),i.rtl)},co=e=>{let t=ro();if(no()){Q("SweetAlert2 requires document to initialize");return}let n=document.createElement("div");n.className=i.container,t&&h(n,i["no-transition"]),H(n,oo),n.dataset.swal2Theme=e.theme;let o=ao(e.target);o.appendChild(n),io(e),lo(o),so()},dt=(e,t)=>{e instanceof HTMLElement?t.appendChild(e):typeof e=="object"?uo(e,t):e&&H(t,e)},uo=(e,t)=>{e.jquery?mo(t,e):H(t,e.toString())},mo=(e,t)=>{if(e.textContent="",0 in t)for(let n=0;n in t;n++)e.appendChild(t[n].cloneNode(!0));else e.appendChild(t.cloneNode(!0))},po=(e,t)=>{let n=be(),o=ie();!n||!o||(!t.showConfirmButton&&!t.showDenyButton&&!t.showCancelButton?T(n):A(n),$(n,t,"actions"),fo(n,o,t),H(o,t.loaderHtml||""),$(o,t,"loader"))};function fo(e,t,n){let o=R(),s=ee(),a=ae();!o||!s||!a||(Ke(o,"confirm",n),Ke(s,"deny",n),Ke(a,"cancel",n),wo(o,s,a,n),n.reverseButtons&&(n.toast?(e.insertBefore(a,o),e.insertBefore(s,o)):(e.insertBefore(a,t),e.insertBefore(s,t),e.insertBefore(o,t))))}function wo(e,t,n,o){if(!o.buttonsStyling){_([e,t,n],i.styled);return}h([e,t,n],i.styled),o.confirmButtonColor&&(e.style.backgroundColor=o.confirmButtonColor,h(e,i["default-outline"])),o.denyButtonColor&&(t.style.backgroundColor=o.denyButtonColor,h(t,i["default-outline"])),o.cancelButtonColor&&(n.style.backgroundColor=o.cancelButtonColor,h(n,i["default-outline"]))}function Ke(e,t,n){let o=tt(t);ve(e,n[`show${o}Button`],"inline-block"),H(e,n[`${t}ButtonText`]||""),e.setAttribute("aria-label",n[`${t}ButtonAriaLabel`]||""),e.className=i[t],$(e,n,`${t}Button`)}var go=(e,t)=>{let n=at();n&&(H(n,t.closeButtonHtml||""),$(n,t,"closeButton"),ve(n,t.showCloseButton),n.setAttribute("aria-label",t.closeButtonAriaLabel||""))},ho=(e,t)=>{let n=B();n&&(yo(n,t.backdrop),bo(n,t.position),vo(n,t.grow),$(n,t,"container"))};function yo(e,t){typeof t=="string"?e.style.background=t:t||h([document.documentElement,document.body],i["no-backdrop"])}function bo(e,t){t&&(t in i?h(e,i[t]):(D('The "position" parameter is not valid, defaulting to "center"'),h(e,i.center)))}function vo(e,t){t&&h(e,i[`grow-${t}`])}var v={innerParams:new WeakMap,domCache:new WeakMap},ko=["input","file","range","select","radio","checkbox","textarea"],Co=(e,t)=>{let n=y();if(!n)return;let o=v.innerParams.get(e),s=!o||t.input!==o.input;ko.forEach(a=>{let d=V(n,i[a]);d&&(So(a,t.inputAttributes),d.className=i[a],s&&T(d))}),t.input&&(s&&xo(t),Po(t))},xo=e=>{if(!e.input)return;if(!S[e.input]){Q(`Unexpected type of input! Expected ${Object.keys(S).join(" | ")}, got "${e.input}"`);return}let t=Yt(e.input);if(!t)return;let n=S[e.input](t,e);A(t),e.inputAutoFocus&&setTimeout(()=>{Ft(n)})},Eo=e=>{for(let t=0;t{let n=y();if(!n)return;let o=Fe(n,e);if(o){Eo(o);for(let s in t)o.setAttribute(s,t[s])}},Po=e=>{if(!e.input)return;let t=Yt(e.input);t&&$(t,e,"input")},mt=(e,t)=>{!e.placeholder&&t.inputPlaceholder&&(e.placeholder=t.inputPlaceholder)},ke=(e,t,n)=>{if(n.inputLabel){let o=document.createElement("label"),s=i["input-label"];o.setAttribute("for",e.id),o.className=s,typeof n.customClass=="object"&&h(o,n.customClass.inputLabel),o.innerText=n.inputLabel,t.insertAdjacentElement("beforebegin",o)}},Yt=e=>{let t=y();if(t)return V(t,i[e]||i.input)},De=(e,t)=>{["string","number"].includes(typeof t)?e.value=`${t}`:ot(t)||D(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof t}"`)},S={};S.text=S.email=S.password=S.number=S.tel=S.url=S.search=S.date=S["datetime-local"]=S.time=S.week=S.month=(e,t)=>(De(e,t.inputValue),ke(e,e,t),mt(e,t),e.type=t.input,e);S.file=(e,t)=>(ke(e,e,t),mt(e,t),e);S.range=(e,t)=>{let n=e.querySelector("input"),o=e.querySelector("output");return De(n,t.inputValue),n.type=t.input,De(o,t.inputValue),ke(n,e,t),e};S.select=(e,t)=>{if(e.textContent="",t.inputPlaceholder){let n=document.createElement("option");H(n,t.inputPlaceholder),n.value="",n.disabled=!0,n.selected=!0,e.appendChild(n)}return ke(e,e,t),e};S.radio=e=>(e.textContent="",e);S.checkbox=(e,t)=>{let n=Fe(y(),"checkbox");n.value="1",n.checked=!!t.inputValue;let o=e.querySelector("span");return H(o,t.inputPlaceholder||t.inputLabel),n};S.textarea=(e,t)=>{De(e,t.inputValue),mt(e,t),ke(e,e,t);let n=o=>parseInt(window.getComputedStyle(o).marginLeft)+parseInt(window.getComputedStyle(o).marginRight);return setTimeout(()=>{if("MutationObserver"in window){let o=parseInt(window.getComputedStyle(y()).width),s=()=>{if(!document.body.contains(e))return;let a=e.offsetWidth+n(e);a>o?y().style.width=`${a}px`:X(y(),"width",t.width)};new MutationObserver(s).observe(e,{attributes:!0,attributeFilter:["style"]})}}),e};var Ao=(e,t)=>{let n=rt();n&&(ct(n),$(n,t,"htmlContainer"),t.html?(dt(t.html,n),A(n,"block")):t.text?(n.textContent=t.text,A(n,"block")):T(n),Co(e,t))},Io=(e,t)=>{let n=qt();n&&(ct(n),ve(n,t.footer,"block"),t.footer&&dt(t.footer,n),$(n,t,"footer"))},To=(e,t)=>{let n=v.innerParams.get(e),o=se();if(!o)return;if(n&&t.icon===n.icon){It(o,t),At(o,t);return}if(!t.icon&&!t.iconHtml){T(o);return}if(t.icon&&Object.keys(Te).indexOf(t.icon)===-1){Q(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${t.icon}"`),T(o);return}A(o),It(o,t),At(o,t),h(o,t.showClass&&t.showClass.icon),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",Vt)},At=(e,t)=>{for(let[n,o]of Object.entries(Te))t.icon!==n&&_(e,o);h(e,t.icon&&Te[t.icon]),Lo(e,t),Vt(),$(e,t,"icon")},Vt=()=>{let e=y();if(!e)return;let t=window.getComputedStyle(e).getPropertyValue("background-color"),n=e.querySelectorAll("[class^=swal2-success-circular-line], .swal2-success-fix");for(let o=0;o

        Join our Discord https://dsc.gg/ProdigyPXP! ⭐ Rate 5 Stars

        -`,Mo=` +`,Bo=` -`,Tt=(e,t)=>{if(!t.icon&&!t.iconHtml)return;let n=e.innerHTML,o="";t.iconHtml?o=Dt(t.iconHtml):t.icon==="success"?(o=Lo,n=n.replace(/ style=".*?"/g,"")):t.icon==="error"?o=Mo:t.icon&&(o=Dt({question:"?",warning:"!",info:"i"}[t.icon])),n.trim()!==o.trim()&&_(e,o)},$o=(e,t)=>{if(t.iconColor){e.style.color=t.iconColor,e.style.borderColor=t.iconColor;for(let n of[".swal2-success-line-tip",".swal2-success-line-long",".swal2-x-mark-line-left",".swal2-x-mark-line-right"])Pt(e,n,"background-color",t.iconColor);Pt(e,".swal2-success-ring","border-color",t.iconColor)}},Dt=e=>`
        ${e}
        `,Oo=(e,t)=>{let n=qt();if(n){if(!t.imageUrl){D(n);return}A(n,""),n.setAttribute("src",t.imageUrl),n.setAttribute("alt",t.imageAlt||""),Z(n,"width",t.imageWidth),Z(n,"height",t.imageHeight),n.className=i.image,O(n,t,"image")}},ft=!1,Gt=0,Kt=0,Xt=0,Zt=0,Ho=e=>{e.addEventListener("mousedown",Le),document.body.addEventListener("mousemove",Me),e.addEventListener("mouseup",$e),e.addEventListener("touchstart",Le),document.body.addEventListener("touchmove",Me),e.addEventListener("touchend",$e)},_o=e=>{e.removeEventListener("mousedown",Le),document.body.removeEventListener("mousemove",Me),e.removeEventListener("mouseup",$e),e.removeEventListener("touchstart",Le),document.body.removeEventListener("touchmove",Me),e.removeEventListener("touchend",$e)},Le=e=>{let t=y();if(e.target===t||ae().contains(e.target)){ft=!0;let n=Jt(e);Gt=n.clientX,Kt=n.clientY,Xt=parseInt(t.style.insetInlineStart)||0,Zt=parseInt(t.style.insetBlockStart)||0,h(t,"swal2-dragging")}},Me=e=>{let t=y();if(ft){let{clientX:n,clientY:o}=Jt(e);t.style.insetInlineStart=`${Xt+(n-Gt)}px`,t.style.insetBlockStart=`${Zt+(o-Kt)}px`}},$e=()=>{let e=y();ft=!1,N(e,"swal2-dragging")},Jt=e=>{let t=0,n=0;return e.type.startsWith("mouse")?(t=e.clientX,n=e.clientY):e.type.startsWith("touch")&&(t=e.touches[0].clientX,n=e.touches[0].clientY),{clientX:t,clientY:n}},No=(e,t)=>{let n=L(),o=y();if(!(!n||!o)){if(t.toast){Z(n,"width",t.width),o.style.width="100%";let s=le();s&&o.insertBefore(s,ae())}else Z(o,"width",t.width);Z(o,"padding",t.padding),t.color&&(o.style.color=t.color),t.background&&(o.style.background=t.background),D(ze()),Ro(o,t),t.draggable&&!t.toast?(h(o,i.draggable),Ho(o)):(N(o,i.draggable),_o(o))}},Ro=(e,t)=>{let n=t.showClass||{};e.className=`${i.popup} ${M(e)?n.popup:""}`,t.toast?(h([document.documentElement,document.body],i["toast-shown"]),h(e,i.toast)):h(e,i.modal),O(e,t,"popup"),typeof t.customClass=="string"&&h(e,t.customClass),t.icon&&h(e,i[`icon-${t.icon}`])},zo=(e,t)=>{let n=at();if(!n)return;let{progressSteps:o,currentProgressStep:s}=t;if(!o||o.length===0||s===void 0){D(n);return}A(n),n.textContent="",s>=o.length&&B("Invalid currentProgressStep parameter, it should be less than progressSteps.length (currentProgressStep like JS arrays starts from 0)"),o.forEach((a,d)=>{let m=qo(a);if(n.appendChild(m),d===s&&h(m,i["active-progress-step"]),d!==o.length-1){let f=Fo(t);n.appendChild(f)}})},qo=e=>{let t=document.createElement("li");return h(t,i["progress-step"]),_(t,e),t},Fo=e=>{let t=document.createElement("li");return h(t,i["progress-step-line"]),e.progressStepsDistance&&Z(t,"width",e.progressStepsDistance),t},jo=(e,t)=>{let n=zt();n&&(ut(n),ke(n,t.title||t.titleText,"block"),t.title&&pt(t.title,n),t.titleText&&(n.innerText=t.titleText),O(n,t,"title"))},Qt=(e,t)=>{No(e,t),bo(e,t),zo(e,t),Bo(e,t),Oo(e,t),jo(e,t),yo(e,t),To(e,t),wo(e,t),Do(e,t);let n=y();typeof t.didRender=="function"&&n&&t.didRender(n),w.eventEmitter.emit("didRender",n)},Wo=()=>M(y()),en=()=>{var e;return(e=z())===null||e===void 0?void 0:e.click()},Yo=()=>{var e;return(e=te())===null||e===void 0?void 0:e.click()},Vo=()=>{var e;return(e=ie())===null||e===void 0?void 0:e.click()},ce=Object.freeze({cancel:"cancel",backdrop:"backdrop",close:"close",esc:"esc",timer:"timer"}),tn=e=>{e.keydownTarget&&e.keydownHandlerAdded&&(e.keydownTarget.removeEventListener("keydown",e.keydownHandler,{capture:e.keydownListenerCapture}),e.keydownHandlerAdded=!1)},Uo=(e,t,n)=>{tn(e),t.toast||(e.keydownHandler=o=>Ko(t,o,n),e.keydownTarget=t.keydownListenerCapture?window:y(),e.keydownListenerCapture=t.keydownListenerCapture,e.keydownTarget.addEventListener("keydown",e.keydownHandler,{capture:e.keydownListenerCapture}),e.keydownHandlerAdded=!0)},Je=(e,t)=>{var n;let o=lt();if(o.length){e=e+t,e===o.length?e=0:e===-1&&(e=o.length-1),o[e].focus();return}(n=y())===null||n===void 0||n.focus()},nn=["ArrowRight","ArrowDown"],Go=["ArrowLeft","ArrowUp"],Ko=(e,t,n)=>{e&&(t.isComposing||t.keyCode===229||(e.stopKeydownPropagation&&t.stopPropagation(),t.key==="Enter"?Xo(t,e):t.key==="Tab"?Zo(t):[...nn,...Go].includes(t.key)?Jo(t.key):t.key==="Escape"&&Qo(t,e,n)))},Xo=(e,t)=>{if(!Re(t.allowEnterKey))return;let n=je(y(),t.input);if(e.target&&n&&e.target instanceof HTMLElement&&e.target.outerHTML===n.outerHTML){if(["textarea","file"].includes(t.input))return;en(),e.preventDefault()}},Zo=e=>{let t=e.target,n=lt(),o=-1;for(let s=0;s{let t=ve(),n=z(),o=te(),s=ie();if(!t||!n||!o||!s)return;let a=[n,o,s];if(document.activeElement instanceof HTMLElement&&!a.includes(document.activeElement))return;let d=nn.includes(e)?"nextElementSibling":"previousElementSibling",m=document.activeElement;if(m){for(let f=0;f{Re(t.allowEscapeKey)&&(e.preventDefault(),n(ce.esc))},re={swalPromiseResolve:new WeakMap,swalPromiseReject:new WeakMap},er=()=>{let e=L();Array.from(document.body.children).forEach(n=>{n.contains(e)||(n.hasAttribute("aria-hidden")&&n.setAttribute("data-previous-aria-hidden",n.getAttribute("aria-hidden")||""),n.setAttribute("aria-hidden","true"))})},on=()=>{Array.from(document.body.children).forEach(t=>{t.hasAttribute("data-previous-aria-hidden")?(t.setAttribute("aria-hidden",t.getAttribute("data-previous-aria-hidden")||""),t.removeAttribute("data-previous-aria-hidden")):t.removeAttribute("aria-hidden")})},rn=typeof window<"u"&&!!window.GestureEvent,tr=()=>{if(rn&&!j(document.body,i.iosfix)){let e=document.body.scrollTop;document.body.style.top=`${e*-1}px`,h(document.body,i.iosfix),nr()}},nr=()=>{let e=L();if(!e)return;let t;e.ontouchstart=n=>{t=or(n)},e.ontouchmove=n=>{t&&(n.preventDefault(),n.stopPropagation())}},or=e=>{let t=e.target,n=L(),o=st();return!n||!o||rr(e)||sr(e)?!1:t===n||!At(n)&&t instanceof HTMLElement&&t.tagName!=="INPUT"&&t.tagName!=="TEXTAREA"&&!(At(o)&&o.contains(t))},rr=e=>e.touches&&e.touches.length&&e.touches[0].touchType==="stylus",sr=e=>e.touches&&e.touches.length>1,ar=()=>{if(j(document.body,i.iosfix)){let e=parseInt(document.body.style.top,10);N(document.body,i.iosfix),document.body.style.top="",document.body.scrollTop=e*-1}},ir=()=>{let e=document.createElement("div");e.className=i["scrollbar-measure"],document.body.appendChild(e);let t=e.getBoundingClientRect().width-e.clientWidth;return document.body.removeChild(e),t},ne=null,lr=e=>{ne===null&&(document.body.scrollHeight>window.innerHeight||e==="scroll")&&(ne=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right")),document.body.style.paddingRight=`${ne+ir()}px`)},cr=()=>{ne!==null&&(document.body.style.paddingRight=`${ne}px`,ne=null)};function sn(e,t,n,o){Fe()?Bt(e,o):(Un(n).then(()=>Bt(e,o)),tn(w)),rn?(t.setAttribute("style","display:none !important"),t.removeAttribute("class"),t.innerHTML=""):t.remove(),ct()&&(cr(),ar(),on()),ur()}function ur(){N([document.documentElement,document.body],[i.shown,i["height-auto"],i["no-backdrop"],i["toast-shown"]])}function G(e){e=pr(e);let t=re.swalPromiseResolve.get(this),n=dr(this);this.isAwaitingPromise?e.isDismissed||(xe(this),t(e)):n&&t(e)}var dr=e=>{let t=y();if(!t)return!1;let n=v.innerParams.get(e);if(!n||j(t,n.hideClass.popup))return!1;N(t,n.showClass.popup),h(t,n.hideClass.popup);let o=L();return N(o,n.showClass.backdrop),h(o,n.hideClass.backdrop),mr(e,t,n),!0};function an(e){let t=re.swalPromiseReject.get(this);xe(this),t&&t(e)}var xe=e=>{e.isAwaitingPromise&&(delete e.isAwaitingPromise,v.innerParams.get(e)||e._destroy())},pr=e=>typeof e>"u"?{isConfirmed:!1,isDenied:!1,isDismissed:!0}:Object.assign({isConfirmed:!1,isDenied:!1,isDismissed:!1},e),mr=(e,t,n)=>{var o;let s=L(),a=Yt(t);typeof n.willClose=="function"&&n.willClose(t),(o=w.eventEmitter)===null||o===void 0||o.emit("willClose",t),a?fr(e,t,s,n.returnFocus,n.didClose):sn(e,s,n.returnFocus,n.didClose)},fr=(e,t,n,o,s)=>{w.swalCloseEventFinishedCallback=sn.bind(null,e,n,o,s);let a=function(d){if(d.target===t){var m;(m=w.swalCloseEventFinishedCallback)===null||m===void 0||m.call(w),delete w.swalCloseEventFinishedCallback,t.removeEventListener("animationend",a),t.removeEventListener("transitionend",a)}};t.addEventListener("animationend",a),t.addEventListener("transitionend",a)},Bt=(e,t)=>{setTimeout(()=>{var n;typeof t=="function"&&t.bind(e.params)(),(n=w.eventEmitter)===null||n===void 0||n.emit("didClose"),e._destroy&&e._destroy()})},se=e=>{let t=y();if(t||new Q,t=y(),!t)return;let n=le();Fe()?D(ae()):wr(t,e),A(n),t.setAttribute("data-loading","true"),t.setAttribute("aria-busy","true"),t.focus()},wr=(e,t)=>{let n=ve(),o=le();!n||!o||(!t&&M(z())&&(t=z()),A(n),t&&(D(t),o.setAttribute("data-button-to-replace",t.className),n.insertBefore(o,t)),h([e,n],i.loading))},gr=(e,t)=>{t.input==="select"||t.input==="radio"?kr(e,t):["text","email","number","tel","textarea"].some(n=>n===t.input)&&(ot(t.inputValue)||rt(t.inputValue))&&(se(z()),Cr(e,t))},hr=(e,t)=>{let n=e.getInput();if(!n)return null;switch(t.input){case"checkbox":return yr(n);case"radio":return br(n);case"file":return vr(n);default:return t.inputAutoTrim?n.value.trim():n.value}},yr=e=>e.checked?1:0,br=e=>e.checked?e.value:null,vr=e=>e.files&&e.files.length?e.getAttribute("multiple")!==null?e.files:e.files[0]:null,kr=(e,t)=>{let n=y();if(!n)return;let o=s=>{t.input==="select"?xr(n,Oe(s),t):t.input==="radio"&&Er(n,Oe(s),t)};ot(t.inputOptions)||rt(t.inputOptions)?(se(z()),ye(t.inputOptions).then(s=>{e.hideLoading(),o(s)})):typeof t.inputOptions=="object"?o(t.inputOptions):ee(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof t.inputOptions}`)},Cr=(e,t)=>{let n=e.getInput();n&&(D(n),ye(t.inputValue).then(o=>{n.value=t.input==="number"?`${parseFloat(o)||0}`:`${o}`,A(n),n.focus(),e.hideLoading()}).catch(o=>{ee(`Error in inputValue promise: ${o}`),n.value="",A(n),n.focus(),e.hideLoading()}))};function xr(e,t,n){let o=U(e,i.select);if(!o)return;let s=(a,d,m)=>{let f=document.createElement("option");f.value=m,_(f,d),f.selected=ln(m,n.inputValue),a.appendChild(f)};t.forEach(a=>{let d=a[0],m=a[1];if(Array.isArray(m)){let f=document.createElement("optgroup");f.label=d,f.disabled=!1,o.appendChild(f),m.forEach(I=>s(f,I[1],I[0]))}else s(o,m,d)}),o.focus()}function Er(e,t,n){let o=U(e,i.radio);if(!o)return;t.forEach(a=>{let d=a[0],m=a[1],f=document.createElement("input"),I=document.createElement("label");f.type="radio",f.name=i.radio,f.value=d,ln(d,n.inputValue)&&(f.checked=!0);let ge=document.createElement("span");_(ge,m),ge.className=i.label,I.appendChild(f),I.appendChild(ge),o.appendChild(I)});let s=o.querySelectorAll("input");s.length&&s[0].focus()}var Oe=e=>{let t=[];return e instanceof Map?e.forEach((n,o)=>{let s=n;typeof s=="object"&&(s=Oe(s)),t.push([o,s])}):Object.keys(e).forEach(n=>{let o=e[n];typeof o=="object"&&(o=Oe(o)),t.push([n,o])}),t},ln=(e,t)=>!!t&&t.toString()===e.toString(),Sr=e=>{let t=v.innerParams.get(e);e.disableButtons(),t.input?cn(e,"confirm"):gt(e,!0)},Pr=e=>{let t=v.innerParams.get(e);e.disableButtons(),t.returnInputValueOnDeny?cn(e,"deny"):wt(e,!1)},Ar=(e,t)=>{e.disableButtons(),t(ce.cancel)},cn=(e,t)=>{let n=v.innerParams.get(e);if(!n.input){ee(`The "input" parameter is needed to be set when using returnInputValueOn${nt(t)}`);return}let o=e.getInput(),s=hr(e,n);n.inputValidator?Ir(e,s,t):o&&!o.checkValidity()?(e.enableButtons(),e.showValidationMessage(n.validationMessage||o.validationMessage)):t==="deny"?wt(e,s):gt(e,s)},Ir=(e,t,n)=>{let o=v.innerParams.get(e);e.disableInput(),Promise.resolve().then(()=>ye(o.inputValidator(t,o.validationMessage))).then(a=>{e.enableButtons(),e.enableInput(),a?e.showValidationMessage(a):n==="deny"?wt(e,t):gt(e,t)})},wt=(e,t)=>{let n=v.innerParams.get(e||void 0);n.showLoaderOnDeny&&se(te()),n.preDeny?(e.isAwaitingPromise=!0,Promise.resolve().then(()=>ye(n.preDeny(t,n.validationMessage))).then(s=>{s===!1?(e.hideLoading(),xe(e)):e.close({isDenied:!0,value:typeof s>"u"?t:s})}).catch(s=>un(e||void 0,s))):e.close({isDenied:!0,value:t})},Lt=(e,t)=>{e.close({isConfirmed:!0,value:t})},un=(e,t)=>{e.rejectPromise(t)},gt=(e,t)=>{let n=v.innerParams.get(e||void 0);n.showLoaderOnConfirm&&se(),n.preConfirm?(e.resetValidationMessage(),e.isAwaitingPromise=!0,Promise.resolve().then(()=>ye(n.preConfirm(t,n.validationMessage))).then(s=>{M(ze())||s===!1?(e.hideLoading(),xe(e)):Lt(e,typeof s>"u"?t:s)}).catch(s=>un(e||void 0,s))):Lt(e,t)};function He(){let e=v.innerParams.get(this);if(!e)return;let t=v.domCache.get(this);D(t.loader),Fe()?e.icon&&A(ae()):Tr(t),N([t.popup,t.actions],i.loading),t.popup.removeAttribute("aria-busy"),t.popup.removeAttribute("data-loading"),t.confirmButton.disabled=!1,t.denyButton.disabled=!1,t.cancelButton.disabled=!1}var Tr=e=>{let t=e.popup.getElementsByClassName(e.loader.getAttribute("data-button-to-replace"));t.length?A(t[0],"inline-block"):no()&&D(e.actions)};function dn(){let e=v.innerParams.get(this),t=v.domCache.get(this);return t?je(t.popup,e.input):null}function pn(e,t,n){let o=v.domCache.get(e);t.forEach(s=>{o[s].disabled=n})}function mn(e,t){let n=y();if(!(!n||!e))if(e.type==="radio"){let o=n.querySelectorAll(`[name="${i.radio}"]`);for(let s=0;sObject.prototype.hasOwnProperty.call(oe,e),kn=e=>Dr.indexOf(e)!==-1,Cn=e=>Br[e],Mr=e=>{vn(e)||B(`Unknown parameter "${e}"`)},$r=e=>{Lr.includes(e)&&B(`The parameter "${e}" is incompatible with toasts`)},Or=e=>{let t=Cn(e);t&&Rt(e,t)},xn=e=>{e.backdrop===!1&&e.allowOutsideClick&&B('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`'),e.theme&&!["light","dark","auto","borderless","embed-iframe"].includes(e.theme)&&B(`Invalid theme "${e.theme}". Expected "light", "dark", "auto", "borderless", or "embed-iframe"`);for(let t in e)Mr(t),e.toast&&$r(t),Or(t)};function En(e){let t=L(),n=y(),o=v.innerParams.get(this);if(!n||j(n,o.hideClass.popup)){B("You're trying to update the closed or closing popup, that won't work. Use the update() method in preConfirm parameter or show a new popup.");return}let s=Hr(e),a=Object.assign({},o,s);xn(a),t.dataset.swal2Theme=a.theme,Qt(this,a),v.innerParams.set(this,a),Object.defineProperties(this,{params:{value:Object.assign({},this.params,e),writable:!1,enumerable:!0}})}var Hr=e=>{let t={};return Object.keys(e).forEach(n=>{kn(n)?t[n]=e[n]:B(`Invalid parameter to update: ${n}`)}),t};function Sn(){let e=v.domCache.get(this),t=v.innerParams.get(this);if(!t){Pn(this);return}e.popup&&w.swalCloseEventFinishedCallback&&(w.swalCloseEventFinishedCallback(),delete w.swalCloseEventFinishedCallback),typeof t.didDestroy=="function"&&t.didDestroy(),w.eventEmitter.emit("didDestroy"),_r(this)}var _r=e=>{Pn(e),delete e.params,delete w.keydownHandler,delete w.keydownTarget,delete w.currentInstance},Pn=e=>{e.isAwaitingPromise?(Ze(v,e),e.isAwaitingPromise=!0):(Ze(re,e),Ze(v,e),delete e.isAwaitingPromise,delete e.disableButtons,delete e.enableButtons,delete e.getInput,delete e.disableInput,delete e.enableInput,delete e.hideLoading,delete e.disableLoading,delete e.showValidationMessage,delete e.resetValidationMessage,delete e.close,delete e.closePopup,delete e.closeModal,delete e.closeToast,delete e.rejectPromise,delete e.update,delete e._destroy)},Ze=(e,t)=>{for(let n in e)e[n].delete(t)},Nr=Object.freeze({__proto__:null,_destroy:Sn,close:G,closeModal:G,closePopup:G,closeToast:G,disableButtons:wn,disableInput:hn,disableLoading:He,enableButtons:fn,enableInput:gn,getInput:dn,handleAwaitingPromise:xe,hideLoading:He,rejectPromise:an,resetValidationMessage:bn,showValidationMessage:yn,update:En}),Rr=(e,t,n)=>{e.toast?zr(e,t,n):(Fr(t),jr(t),Wr(e,t,n))},zr=(e,t,n)=>{t.popup.onclick=()=>{e&&(qr(e)||e.timer||e.input)||n(ce.close)}},qr=e=>!!(e.showConfirmButton||e.showDenyButton||e.showCancelButton||e.showCloseButton),_e=!1,Fr=e=>{e.popup.onmousedown=()=>{e.container.onmouseup=function(t){e.container.onmouseup=()=>{},t.target===e.container&&(_e=!0)}}},jr=e=>{e.container.onmousedown=t=>{t.target===e.container&&t.preventDefault(),e.popup.onmouseup=function(n){e.popup.onmouseup=()=>{},(n.target===e.popup||n.target instanceof HTMLElement&&e.popup.contains(n.target))&&(_e=!0)}}},Wr=(e,t,n)=>{t.container.onclick=o=>{if(_e){_e=!1;return}o.target===t.container&&Re(e.allowOutsideClick)&&n(ce.backdrop)}},Yr=e=>typeof e=="object"&&e.jquery,Mt=e=>e instanceof Element||Yr(e),Vr=e=>{let t={};return typeof e[0]=="object"&&!Mt(e[0])?Object.assign(t,e[0]):["title","html","icon"].forEach((n,o)=>{let s=e[o];typeof s=="string"||Mt(s)?t[n]=s:s!==void 0&&ee(`Unexpected type of ${n}! Expected "string" or "Element", got ${typeof s}`)}),t};function Ur(){for(var e=arguments.length,t=new Array(e),n=0;nw.timeout&&w.timeout.getTimerLeft(),An=()=>{if(w.timeout)return oo(),w.timeout.stop()},In=()=>{if(w.timeout){let e=w.timeout.start();return dt(e),e}},Xr=()=>{let e=w.timeout;return e&&(e.running?An():In())},Zr=e=>{if(w.timeout){let t=w.timeout.increase(e);return dt(t,!0),t}},Jr=()=>!!(w.timeout&&w.timeout.isRunning()),$t=!1,Qe={};function Qr(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:"data-swal-template";Qe[e]=this,$t||(document.body.addEventListener("click",es),$t=!0)}var es=e=>{for(let t=e.target;t&&t!==document;t=t.parentNode)for(let n in Qe){let o=t.getAttribute(n);if(o){Qe[n].fire({template:o});return}}},et=class{constructor(){this.events={}}_getHandlersByEventName(t){return typeof this.events[t]>"u"&&(this.events[t]=[]),this.events[t]}on(t,n){let o=this._getHandlersByEventName(t);o.includes(n)||o.push(n)}once(t,n){var o=this;let s=function(){o.removeListener(t,s);for(var a=arguments.length,d=new Array(a),m=0;m1?n-1:0),s=1;s{try{a.apply(this,o)}catch(d){console.error(d)}})}removeListener(t,n){let o=this._getHandlersByEventName(t),s=o.indexOf(n);s>-1&&o.splice(s,1)}removeAllListeners(t){this.events[t]!==void 0&&(this.events[t].length=0)}reset(){this.events={}}};w.eventEmitter=new et;var ts=(e,t)=>{w.eventEmitter.on(e,t)},ns=(e,t)=>{w.eventEmitter.once(e,t)},os=(e,t)=>{if(!e){w.eventEmitter.reset();return}t?w.eventEmitter.removeListener(e,t):w.eventEmitter.removeAllListeners(e)},rs=Object.freeze({__proto__:null,argsToParams:Vr,bindClickHandler:Qr,clickCancel:Vo,clickConfirm:en,clickDeny:Yo,enableLoading:se,fire:Ur,getActions:ve,getCancelButton:ie,getCloseButton:it,getConfirmButton:z,getContainer:L,getDenyButton:te,getFocusableElements:lt,getFooter:Ft,getHtmlContainer:st,getIcon:ae,getIconContent:Zn,getImage:qt,getInputLabel:Jn,getLoader:le,getPopup:y,getProgressSteps:at,getTimerLeft:Kr,getTimerProgressBar:qe,getTitle:zt,getValidationMessage:ze,increaseTimer:Zr,isDeprecatedParameter:Cn,isLoading:eo,isTimerRunning:Jr,isUpdatableParameter:kn,isValidParameter:vn,isVisible:Wo,mixin:Gr,off:os,on:ts,once:ns,resumeTimer:In,showLoading:se,stopTimer:An,toggleTimer:Xr}),tt=class{constructor(t,n){this.callback=t,this.remaining=n,this.running=!1,this.start()}start(){return this.running||(this.running=!0,this.started=new Date,this.id=setTimeout(this.callback,this.remaining)),this.remaining}stop(){return this.started&&this.running&&(this.running=!1,clearTimeout(this.id),this.remaining-=new Date().getTime()-this.started.getTime()),this.remaining}increase(t){let n=this.running;return n&&this.stop(),this.remaining+=t,n&&this.start(),this.remaining}getTimerLeft(){return this.running&&(this.stop(),this.start()),this.remaining}isRunning(){return this.running}},Tn=["swal-title","swal-html","swal-footer"],ss=e=>{let t=typeof e.template=="string"?document.querySelector(e.template):e.template;if(!t)return{};let n=t.content;return ms(n),Object.assign(as(n),is(n),ls(n),cs(n),us(n),ds(n),ps(n,Tn))},as=e=>{let t={};return Array.from(e.querySelectorAll("swal-param")).forEach(o=>{J(o,["name","value"]);let s=o.getAttribute("name"),a=o.getAttribute("value");!s||!a||(typeof oe[s]=="boolean"?t[s]=a!=="false":typeof oe[s]=="object"?t[s]=JSON.parse(a):t[s]=a)}),t},is=e=>{let t={};return Array.from(e.querySelectorAll("swal-function-param")).forEach(o=>{let s=o.getAttribute("name"),a=o.getAttribute("value");!s||!a||(t[s]=new Function(`return ${a}`)())}),t},ls=e=>{let t={};return Array.from(e.querySelectorAll("swal-button")).forEach(o=>{J(o,["type","color","aria-label"]);let s=o.getAttribute("type");!s||!["confirm","cancel","deny"].includes(s)||(t[`${s}ButtonText`]=o.innerHTML,t[`show${nt(s)}Button`]=!0,o.hasAttribute("color")&&(t[`${s}ButtonColor`]=o.getAttribute("color")),o.hasAttribute("aria-label")&&(t[`${s}ButtonAriaLabel`]=o.getAttribute("aria-label")))}),t},cs=e=>{let t={},n=e.querySelector("swal-image");return n&&(J(n,["src","width","height","alt"]),n.hasAttribute("src")&&(t.imageUrl=n.getAttribute("src")||void 0),n.hasAttribute("width")&&(t.imageWidth=n.getAttribute("width")||void 0),n.hasAttribute("height")&&(t.imageHeight=n.getAttribute("height")||void 0),n.hasAttribute("alt")&&(t.imageAlt=n.getAttribute("alt")||void 0)),t},us=e=>{let t={},n=e.querySelector("swal-icon");return n&&(J(n,["type","color"]),n.hasAttribute("type")&&(t.icon=n.getAttribute("type")),n.hasAttribute("color")&&(t.iconColor=n.getAttribute("color")),t.iconHtml=n.innerHTML),t},ds=e=>{let t={},n=e.querySelector("swal-input");n&&(J(n,["type","label","placeholder","value"]),t.input=n.getAttribute("type")||"text",n.hasAttribute("label")&&(t.inputLabel=n.getAttribute("label")),n.hasAttribute("placeholder")&&(t.inputPlaceholder=n.getAttribute("placeholder")),n.hasAttribute("value")&&(t.inputValue=n.getAttribute("value")));let o=Array.from(e.querySelectorAll("swal-input-option"));return o.length&&(t.inputOptions={},o.forEach(s=>{J(s,["value"]);let a=s.getAttribute("value");if(!a)return;let d=s.innerHTML;t.inputOptions[a]=d})),t},ps=(e,t)=>{let n={};for(let o in t){let s=t[o],a=e.querySelector(s);a&&(J(a,[]),n[s.replace(/^swal-/,"")]=a.innerHTML.trim())}return n},ms=e=>{let t=Tn.concat(["swal-param","swal-function-param","swal-button","swal-image","swal-icon","swal-input","swal-input-option"]);Array.from(e.children).forEach(n=>{let o=n.tagName.toLowerCase();t.includes(o)||B(`Unrecognized element <${o}>`)})},J=(e,t)=>{Array.from(e.attributes).forEach(n=>{t.indexOf(n.name)===-1&&B([`Unrecognized attribute "${n.name}" on <${e.tagName.toLowerCase()}>.`,`${t.length?`Allowed attributes are: ${t.join(", ")}`:"To set the value, use HTML within the element."}`])})},Dn=10,fs=e=>{let t=L(),n=y();typeof e.willOpen=="function"&&e.willOpen(n),w.eventEmitter.emit("willOpen",n);let s=window.getComputedStyle(document.body).overflowY;hs(t,n,e),setTimeout(()=>{ws(t,n)},Dn),ct()&&(gs(t,e.scrollbarPadding,s),er()),!Fe()&&!w.previousActiveElement&&(w.previousActiveElement=document.activeElement),typeof e.didOpen=="function"&&setTimeout(()=>e.didOpen(n)),w.eventEmitter.emit("didOpen",n),N(t,i["no-transition"])},Ne=e=>{let t=y();if(e.target!==t)return;let n=L();t.removeEventListener("animationend",Ne),t.removeEventListener("transitionend",Ne),n.style.overflowY="auto"},ws=(e,t)=>{Yt(t)?(e.style.overflowY="hidden",t.addEventListener("animationend",Ne),t.addEventListener("transitionend",Ne)):e.style.overflowY="auto"},gs=(e,t,n)=>{tr(),t&&n!=="hidden"&&lr(n),setTimeout(()=>{e.scrollTop=0})},hs=(e,t,n)=>{h(e,n.showClass.backdrop),n.animation?(t.style.setProperty("opacity","0","important"),A(t,"grid"),setTimeout(()=>{h(t,n.showClass.popup),t.style.removeProperty("opacity")},Dn)):A(t,"grid"),h([document.documentElement,document.body],i.shown),n.heightAuto&&n.backdrop&&!n.toast&&h([document.documentElement,document.body],i["height-auto"])},Ot={email:(e,t)=>/^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(e)?Promise.resolve():Promise.resolve(t||"Invalid email address"),url:(e,t)=>/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-z]{2,63}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/.test(e)?Promise.resolve():Promise.resolve(t||"Invalid URL")};function ys(e){e.inputValidator||(e.input==="email"&&(e.inputValidator=Ot.email),e.input==="url"&&(e.inputValidator=Ot.url))}function bs(e){(!e.target||typeof e.target=="string"&&!document.querySelector(e.target)||typeof e.target!="string"&&!e.target.appendChild)&&(B('Target parameter is not valid, defaulting to "body"'),e.target="body")}function vs(e){ys(e),e.showLoaderOnConfirm&&!e.preConfirm&&B(`showLoaderOnConfirm is set to true, but preConfirm is not defined. +`,It=(e,t)=>{if(!t.icon&&!t.iconHtml)return;let n=e.innerHTML,o="";t.iconHtml?o=Tt(t.iconHtml):t.icon==="success"?(o=Do,n=n.replace(/ style=".*?"/g,"")):t.icon==="error"?o=Bo:t.icon&&(o=Tt({question:"?",warning:"!",info:"i"}[t.icon])),n.trim()!==o.trim()&&H(e,o)},Lo=(e,t)=>{if(t.iconColor){e.style.color=t.iconColor,e.style.borderColor=t.iconColor;for(let n of[".swal2-success-line-tip",".swal2-success-line-long",".swal2-x-mark-line-left",".swal2-x-mark-line-right"])St(e,n,"background-color",t.iconColor);St(e,".swal2-success-ring","border-color",t.iconColor)}},Tt=e=>`
        ${e}
        `,Mo=(e,t)=>{let n=zt();if(n){if(!t.imageUrl){T(n);return}A(n,""),n.setAttribute("src",t.imageUrl),n.setAttribute("alt",t.imageAlt||""),X(n,"width",t.imageWidth),X(n,"height",t.imageHeight),n.className=i.image,$(n,t,"image")}},pt=!1,Ut=0,Gt=0,Kt=0,Xt=0,$o=e=>{e.addEventListener("mousedown",Be),document.body.addEventListener("mousemove",Le),e.addEventListener("mouseup",Me),e.addEventListener("touchstart",Be),document.body.addEventListener("touchmove",Le),e.addEventListener("touchend",Me)},Oo=e=>{e.removeEventListener("mousedown",Be),document.body.removeEventListener("mousemove",Le),e.removeEventListener("mouseup",Me),e.removeEventListener("touchstart",Be),document.body.removeEventListener("touchmove",Le),e.removeEventListener("touchend",Me)},Be=e=>{let t=y();if(e.target===t||se().contains(e.target)){pt=!0;let n=Zt(e);Ut=n.clientX,Gt=n.clientY,Kt=parseInt(t.style.insetInlineStart)||0,Xt=parseInt(t.style.insetBlockStart)||0,h(t,"swal2-dragging")}},Le=e=>{let t=y();if(pt){let{clientX:n,clientY:o}=Zt(e);t.style.insetInlineStart=`${Kt+(n-Ut)}px`,t.style.insetBlockStart=`${Xt+(o-Gt)}px`}},Me=()=>{let e=y();pt=!1,_(e,"swal2-dragging")},Zt=e=>{let t=0,n=0;return e.type.startsWith("mouse")?(t=e.clientX,n=e.clientY):e.type.startsWith("touch")&&(t=e.touches[0].clientX,n=e.touches[0].clientY),{clientX:t,clientY:n}},Ho=(e,t)=>{let n=B(),o=y();if(!(!n||!o)){if(t.toast){X(n,"width",t.width),o.style.width="100%";let s=ie();s&&o.insertBefore(s,se())}else X(o,"width",t.width);X(o,"padding",t.padding),t.color&&(o.style.color=t.color),t.background&&(o.style.background=t.background),T(Re()),_o(o,t),t.draggable&&!t.toast?(h(o,i.draggable),$o(o)):(_(o,i.draggable),Oo(o))}},_o=(e,t)=>{let n=t.showClass||{};e.className=`${i.popup} ${L(e)?n.popup:""}`,t.toast?(h([document.documentElement,document.body],i["toast-shown"]),h(e,i.toast)):h(e,i.modal),$(e,t,"popup"),typeof t.customClass=="string"&&h(e,t.customClass),t.icon&&h(e,i[`icon-${t.icon}`])},No=(e,t)=>{let n=st();if(!n)return;let{progressSteps:o,currentProgressStep:s}=t;if(!o||o.length===0||s===void 0){T(n);return}A(n),n.textContent="",s>=o.length&&D("Invalid currentProgressStep parameter, it should be less than progressSteps.length (currentProgressStep like JS arrays starts from 0)"),o.forEach((a,d)=>{let p=Ro(a);if(n.appendChild(p),d===s&&h(p,i["active-progress-step"]),d!==o.length-1){let f=zo(t);n.appendChild(f)}})},Ro=e=>{let t=document.createElement("li");return h(t,i["progress-step"]),H(t,e),t},zo=e=>{let t=document.createElement("li");return h(t,i["progress-step-line"]),e.progressStepsDistance&&X(t,"width",e.progressStepsDistance),t},qo=(e,t)=>{let n=Rt();n&&(ct(n),ve(n,t.title||t.titleText,"block"),t.title&&dt(t.title,n),t.titleText&&(n.innerText=t.titleText),$(n,t,"title"))},Jt=(e,t)=>{Ho(e,t),ho(e,t),No(e,t),To(e,t),Mo(e,t),qo(e,t),go(e,t),Ao(e,t),po(e,t),Io(e,t);let n=y();typeof t.didRender=="function"&&n&&t.didRender(n),w.eventEmitter.emit("didRender",n)},Fo=()=>L(y()),Qt=()=>{var e;return(e=R())===null||e===void 0?void 0:e.click()},jo=()=>{var e;return(e=ee())===null||e===void 0?void 0:e.click()},Wo=()=>{var e;return(e=ae())===null||e===void 0?void 0:e.click()},le=Object.freeze({cancel:"cancel",backdrop:"backdrop",close:"close",esc:"esc",timer:"timer"}),en=e=>{e.keydownTarget&&e.keydownHandlerAdded&&(e.keydownTarget.removeEventListener("keydown",e.keydownHandler,{capture:e.keydownListenerCapture}),e.keydownHandlerAdded=!1)},Yo=(e,t,n)=>{en(e),t.toast||(e.keydownHandler=o=>Uo(t,o,n),e.keydownTarget=t.keydownListenerCapture?window:y(),e.keydownListenerCapture=t.keydownListenerCapture,e.keydownTarget.addEventListener("keydown",e.keydownHandler,{capture:e.keydownListenerCapture}),e.keydownHandlerAdded=!0)},Ze=(e,t)=>{var n;let o=it();if(o.length){e=e+t,e===o.length?e=0:e===-1&&(e=o.length-1),o[e].focus();return}(n=y())===null||n===void 0||n.focus()},tn=["ArrowRight","ArrowDown"],Vo=["ArrowLeft","ArrowUp"],Uo=(e,t,n)=>{e&&(t.isComposing||t.keyCode===229||(e.stopKeydownPropagation&&t.stopPropagation(),t.key==="Enter"?Go(t,e):t.key==="Tab"?Ko(t):[...tn,...Vo].includes(t.key)?Xo(t.key):t.key==="Escape"&&Zo(t,e,n)))},Go=(e,t)=>{if(!Ne(t.allowEnterKey))return;let n=Fe(y(),t.input);if(e.target&&n&&e.target instanceof HTMLElement&&e.target.outerHTML===n.outerHTML){if(["textarea","file"].includes(t.input))return;Qt(),e.preventDefault()}},Ko=e=>{let t=e.target,n=it(),o=-1;for(let s=0;s{let t=be(),n=R(),o=ee(),s=ae();if(!t||!n||!o||!s)return;let a=[n,o,s];if(document.activeElement instanceof HTMLElement&&!a.includes(document.activeElement))return;let d=tn.includes(e)?"nextElementSibling":"previousElementSibling",p=document.activeElement;if(p){for(let f=0;f{Ne(t.allowEscapeKey)&&(e.preventDefault(),n(le.esc))},oe={swalPromiseResolve:new WeakMap,swalPromiseReject:new WeakMap},Jo=()=>{let e=B();Array.from(document.body.children).forEach(n=>{n.contains(e)||(n.hasAttribute("aria-hidden")&&n.setAttribute("data-previous-aria-hidden",n.getAttribute("aria-hidden")||""),n.setAttribute("aria-hidden","true"))})},nn=()=>{Array.from(document.body.children).forEach(t=>{t.hasAttribute("data-previous-aria-hidden")?(t.setAttribute("aria-hidden",t.getAttribute("data-previous-aria-hidden")||""),t.removeAttribute("data-previous-aria-hidden")):t.removeAttribute("aria-hidden")})},on=typeof window<"u"&&!!window.GestureEvent,Qo=()=>{if(on&&!F(document.body,i.iosfix)){let e=document.body.scrollTop;document.body.style.top=`${e*-1}px`,h(document.body,i.iosfix),er()}},er=()=>{let e=B();if(!e)return;let t;e.ontouchstart=n=>{t=tr(n)},e.ontouchmove=n=>{t&&(n.preventDefault(),n.stopPropagation())}},tr=e=>{let t=e.target,n=B(),o=rt();return!n||!o||nr(e)||or(e)?!1:t===n||!Pt(n)&&t instanceof HTMLElement&&t.tagName!=="INPUT"&&t.tagName!=="TEXTAREA"&&!(Pt(o)&&o.contains(t))},nr=e=>e.touches&&e.touches.length&&e.touches[0].touchType==="stylus",or=e=>e.touches&&e.touches.length>1,rr=()=>{if(F(document.body,i.iosfix)){let e=parseInt(document.body.style.top,10);_(document.body,i.iosfix),document.body.style.top="",document.body.scrollTop=e*-1}},sr=()=>{let e=document.createElement("div");e.className=i["scrollbar-measure"],document.body.appendChild(e);let t=e.getBoundingClientRect().width-e.clientWidth;return document.body.removeChild(e),t},te=null,ar=e=>{te===null&&(document.body.scrollHeight>window.innerHeight||e==="scroll")&&(te=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right")),document.body.style.paddingRight=`${te+sr()}px`)},ir=()=>{te!==null&&(document.body.style.paddingRight=`${te}px`,te=null)};function rn(e,t,n,o){qe()?Dt(e,o):(Yn(n).then(()=>Dt(e,o)),en(w)),on?(t.setAttribute("style","display:none !important"),t.removeAttribute("class"),t.innerHTML=""):t.remove(),lt()&&(ir(),rr(),nn()),lr()}function lr(){_([document.documentElement,document.body],[i.shown,i["height-auto"],i["no-backdrop"],i["toast-shown"]])}function U(e){e=ur(e);let t=oe.swalPromiseResolve.get(this),n=cr(this);this.isAwaitingPromise?e.isDismissed||(Ce(this),t(e)):n&&t(e)}var cr=e=>{let t=y();if(!t)return!1;let n=v.innerParams.get(e);if(!n||F(t,n.hideClass.popup))return!1;_(t,n.showClass.popup),h(t,n.hideClass.popup);let o=B();return _(o,n.showClass.backdrop),h(o,n.hideClass.backdrop),dr(e,t,n),!0};function sn(e){let t=oe.swalPromiseReject.get(this);Ce(this),t&&t(e)}var Ce=e=>{e.isAwaitingPromise&&(delete e.isAwaitingPromise,v.innerParams.get(e)||e._destroy())},ur=e=>typeof e>"u"?{isConfirmed:!1,isDenied:!1,isDismissed:!0}:Object.assign({isConfirmed:!1,isDenied:!1,isDismissed:!1},e),dr=(e,t,n)=>{var o;let s=B(),a=Wt(t);typeof n.willClose=="function"&&n.willClose(t),(o=w.eventEmitter)===null||o===void 0||o.emit("willClose",t),a?mr(e,t,s,n.returnFocus,n.didClose):rn(e,s,n.returnFocus,n.didClose)},mr=(e,t,n,o,s)=>{w.swalCloseEventFinishedCallback=rn.bind(null,e,n,o,s);let a=function(d){if(d.target===t){var p;(p=w.swalCloseEventFinishedCallback)===null||p===void 0||p.call(w),delete w.swalCloseEventFinishedCallback,t.removeEventListener("animationend",a),t.removeEventListener("transitionend",a)}};t.addEventListener("animationend",a),t.addEventListener("transitionend",a)},Dt=(e,t)=>{setTimeout(()=>{var n;typeof t=="function"&&t.bind(e.params)(),(n=w.eventEmitter)===null||n===void 0||n.emit("didClose"),e._destroy&&e._destroy()})},re=e=>{let t=y();if(t||new J,t=y(),!t)return;let n=ie();qe()?T(se()):pr(t,e),A(n),t.setAttribute("data-loading","true"),t.setAttribute("aria-busy","true"),t.focus()},pr=(e,t)=>{let n=be(),o=ie();!n||!o||(!t&&L(R())&&(t=R()),A(n),t&&(T(t),o.setAttribute("data-button-to-replace",t.className),n.insertBefore(o,t)),h([e,n],i.loading))},fr=(e,t)=>{t.input==="select"||t.input==="radio"?br(e,t):["text","email","number","tel","textarea"].some(n=>n===t.input)&&(nt(t.inputValue)||ot(t.inputValue))&&(re(R()),vr(e,t))},wr=(e,t)=>{let n=e.getInput();if(!n)return null;switch(t.input){case"checkbox":return gr(n);case"radio":return hr(n);case"file":return yr(n);default:return t.inputAutoTrim?n.value.trim():n.value}},gr=e=>e.checked?1:0,hr=e=>e.checked?e.value:null,yr=e=>e.files&&e.files.length?e.getAttribute("multiple")!==null?e.files:e.files[0]:null,br=(e,t)=>{let n=y();if(!n)return;let o=s=>{t.input==="select"?kr(n,$e(s),t):t.input==="radio"&&Cr(n,$e(s),t)};nt(t.inputOptions)||ot(t.inputOptions)?(re(R()),he(t.inputOptions).then(s=>{e.hideLoading(),o(s)})):typeof t.inputOptions=="object"?o(t.inputOptions):Q(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof t.inputOptions}`)},vr=(e,t)=>{let n=e.getInput();n&&(T(n),he(t.inputValue).then(o=>{n.value=t.input==="number"?`${parseFloat(o)||0}`:`${o}`,A(n),n.focus(),e.hideLoading()}).catch(o=>{Q(`Error in inputValue promise: ${o}`),n.value="",A(n),n.focus(),e.hideLoading()}))};function kr(e,t,n){let o=V(e,i.select);if(!o)return;let s=(a,d,p)=>{let f=document.createElement("option");f.value=p,H(f,d),f.selected=an(p,n.inputValue),a.appendChild(f)};t.forEach(a=>{let d=a[0],p=a[1];if(Array.isArray(p)){let f=document.createElement("optgroup");f.label=d,f.disabled=!1,o.appendChild(f),p.forEach(I=>s(f,I[1],I[0]))}else s(o,p,d)}),o.focus()}function Cr(e,t,n){let o=V(e,i.radio);if(!o)return;t.forEach(a=>{let d=a[0],p=a[1],f=document.createElement("input"),I=document.createElement("label");f.type="radio",f.name=i.radio,f.value=d,an(d,n.inputValue)&&(f.checked=!0);let we=document.createElement("span");H(we,p),we.className=i.label,I.appendChild(f),I.appendChild(we),o.appendChild(I)});let s=o.querySelectorAll("input");s.length&&s[0].focus()}var $e=e=>{let t=[];return e instanceof Map?e.forEach((n,o)=>{let s=n;typeof s=="object"&&(s=$e(s)),t.push([o,s])}):Object.keys(e).forEach(n=>{let o=e[n];typeof o=="object"&&(o=$e(o)),t.push([n,o])}),t},an=(e,t)=>!!t&&t.toString()===e.toString(),xr=e=>{let t=v.innerParams.get(e);e.disableButtons(),t.input?ln(e,"confirm"):wt(e,!0)},Er=e=>{let t=v.innerParams.get(e);e.disableButtons(),t.returnInputValueOnDeny?ln(e,"deny"):ft(e,!1)},Sr=(e,t)=>{e.disableButtons(),t(le.cancel)},ln=(e,t)=>{let n=v.innerParams.get(e);if(!n.input){Q(`The "input" parameter is needed to be set when using returnInputValueOn${tt(t)}`);return}let o=e.getInput(),s=wr(e,n);n.inputValidator?Pr(e,s,t):o&&!o.checkValidity()?(e.enableButtons(),e.showValidationMessage(n.validationMessage||o.validationMessage)):t==="deny"?ft(e,s):wt(e,s)},Pr=(e,t,n)=>{let o=v.innerParams.get(e);e.disableInput(),Promise.resolve().then(()=>he(o.inputValidator(t,o.validationMessage))).then(a=>{e.enableButtons(),e.enableInput(),a?e.showValidationMessage(a):n==="deny"?ft(e,t):wt(e,t)})},ft=(e,t)=>{let n=v.innerParams.get(e||void 0);n.showLoaderOnDeny&&re(ee()),n.preDeny?(e.isAwaitingPromise=!0,Promise.resolve().then(()=>he(n.preDeny(t,n.validationMessage))).then(s=>{s===!1?(e.hideLoading(),Ce(e)):e.close({isDenied:!0,value:typeof s>"u"?t:s})}).catch(s=>cn(e||void 0,s))):e.close({isDenied:!0,value:t})},Bt=(e,t)=>{e.close({isConfirmed:!0,value:t})},cn=(e,t)=>{e.rejectPromise(t)},wt=(e,t)=>{let n=v.innerParams.get(e||void 0);n.showLoaderOnConfirm&&re(),n.preConfirm?(e.resetValidationMessage(),e.isAwaitingPromise=!0,Promise.resolve().then(()=>he(n.preConfirm(t,n.validationMessage))).then(s=>{L(Re())||s===!1?(e.hideLoading(),Ce(e)):Bt(e,typeof s>"u"?t:s)}).catch(s=>cn(e||void 0,s))):Bt(e,t)};function Oe(){let e=v.innerParams.get(this);if(!e)return;let t=v.domCache.get(this);T(t.loader),qe()?e.icon&&A(se()):Ar(t),_([t.popup,t.actions],i.loading),t.popup.removeAttribute("aria-busy"),t.popup.removeAttribute("data-loading"),t.confirmButton.disabled=!1,t.denyButton.disabled=!1,t.cancelButton.disabled=!1}var Ar=e=>{let t=e.popup.getElementsByClassName(e.loader.getAttribute("data-button-to-replace"));t.length?A(t[0],"inline-block"):eo()&&T(e.actions)};function un(){let e=v.innerParams.get(this),t=v.domCache.get(this);return t?Fe(t.popup,e.input):null}function dn(e,t,n){let o=v.domCache.get(e);t.forEach(s=>{o[s].disabled=n})}function mn(e,t){let n=y();if(!(!n||!e))if(e.type==="radio"){let o=n.querySelectorAll(`[name="${i.radio}"]`);for(let s=0;sObject.prototype.hasOwnProperty.call(ne,e),vn=e=>Ir.indexOf(e)!==-1,kn=e=>Tr[e],Br=e=>{bn(e)||D(`Unknown parameter "${e}"`)},Lr=e=>{Dr.includes(e)&&D(`The parameter "${e}" is incompatible with toasts`)},Mr=e=>{let t=kn(e);t&&Nt(e,t)},Cn=e=>{e.backdrop===!1&&e.allowOutsideClick&&D('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`'),e.theme&&!["light","dark","auto","borderless","embed-iframe"].includes(e.theme)&&D(`Invalid theme "${e.theme}". Expected "light", "dark", "auto", "borderless", or "embed-iframe"`);for(let t in e)Br(t),e.toast&&Lr(t),Mr(t)};function xn(e){let t=B(),n=y(),o=v.innerParams.get(this);if(!n||F(n,o.hideClass.popup)){D("You're trying to update the closed or closing popup, that won't work. Use the update() method in preConfirm parameter or show a new popup.");return}let s=$r(e),a=Object.assign({},o,s);Cn(a),t.dataset.swal2Theme=a.theme,Jt(this,a),v.innerParams.set(this,a),Object.defineProperties(this,{params:{value:Object.assign({},this.params,e),writable:!1,enumerable:!0}})}var $r=e=>{let t={};return Object.keys(e).forEach(n=>{vn(n)?t[n]=e[n]:D(`Invalid parameter to update: ${n}`)}),t};function En(){let e=v.domCache.get(this),t=v.innerParams.get(this);if(!t){Sn(this);return}e.popup&&w.swalCloseEventFinishedCallback&&(w.swalCloseEventFinishedCallback(),delete w.swalCloseEventFinishedCallback),typeof t.didDestroy=="function"&&t.didDestroy(),w.eventEmitter.emit("didDestroy"),Or(this)}var Or=e=>{Sn(e),delete e.params,delete w.keydownHandler,delete w.keydownTarget,delete w.currentInstance},Sn=e=>{e.isAwaitingPromise?(Xe(v,e),e.isAwaitingPromise=!0):(Xe(oe,e),Xe(v,e),delete e.isAwaitingPromise,delete e.disableButtons,delete e.enableButtons,delete e.getInput,delete e.disableInput,delete e.enableInput,delete e.hideLoading,delete e.disableLoading,delete e.showValidationMessage,delete e.resetValidationMessage,delete e.close,delete e.closePopup,delete e.closeModal,delete e.closeToast,delete e.rejectPromise,delete e.update,delete e._destroy)},Xe=(e,t)=>{for(let n in e)e[n].delete(t)},Hr=Object.freeze({__proto__:null,_destroy:En,close:U,closeModal:U,closePopup:U,closeToast:U,disableButtons:fn,disableInput:gn,disableLoading:Oe,enableButtons:pn,enableInput:wn,getInput:un,handleAwaitingPromise:Ce,hideLoading:Oe,rejectPromise:sn,resetValidationMessage:yn,showValidationMessage:hn,update:xn}),_r=(e,t,n)=>{e.toast?Nr(e,t,n):(zr(t),qr(t),Fr(e,t,n))},Nr=(e,t,n)=>{t.popup.onclick=()=>{e&&(Rr(e)||e.timer||e.input)||n(le.close)}},Rr=e=>!!(e.showConfirmButton||e.showDenyButton||e.showCancelButton||e.showCloseButton),He=!1,zr=e=>{e.popup.onmousedown=()=>{e.container.onmouseup=function(t){e.container.onmouseup=()=>{},t.target===e.container&&(He=!0)}}},qr=e=>{e.container.onmousedown=t=>{t.target===e.container&&t.preventDefault(),e.popup.onmouseup=function(n){e.popup.onmouseup=()=>{},(n.target===e.popup||n.target instanceof HTMLElement&&e.popup.contains(n.target))&&(He=!0)}}},Fr=(e,t,n)=>{t.container.onclick=o=>{if(He){He=!1;return}o.target===t.container&&Ne(e.allowOutsideClick)&&n(le.backdrop)}},jr=e=>typeof e=="object"&&e.jquery,Lt=e=>e instanceof Element||jr(e),Wr=e=>{let t={};return typeof e[0]=="object"&&!Lt(e[0])?Object.assign(t,e[0]):["title","html","icon"].forEach((n,o)=>{let s=e[o];typeof s=="string"||Lt(s)?t[n]=s:s!==void 0&&Q(`Unexpected type of ${n}! Expected "string" or "Element", got ${typeof s}`)}),t};function Yr(){for(var e=arguments.length,t=new Array(e),n=0;nw.timeout&&w.timeout.getTimerLeft(),Pn=()=>{if(w.timeout)return to(),w.timeout.stop()},An=()=>{if(w.timeout){let e=w.timeout.start();return ut(e),e}},Gr=()=>{let e=w.timeout;return e&&(e.running?Pn():An())},Kr=e=>{if(w.timeout){let t=w.timeout.increase(e);return ut(t,!0),t}},Xr=()=>!!(w.timeout&&w.timeout.isRunning()),Mt=!1,Je={};function Zr(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:"data-swal-template";Je[e]=this,Mt||(document.body.addEventListener("click",Jr),Mt=!0)}var Jr=e=>{for(let t=e.target;t&&t!==document;t=t.parentNode)for(let n in Je){let o=t.getAttribute(n);if(o){Je[n].fire({template:o});return}}},Qe=class{constructor(){this.events={}}_getHandlersByEventName(t){return typeof this.events[t]>"u"&&(this.events[t]=[]),this.events[t]}on(t,n){let o=this._getHandlersByEventName(t);o.includes(n)||o.push(n)}once(t,n){var o=this;let s=function(){o.removeListener(t,s);for(var a=arguments.length,d=new Array(a),p=0;p1?n-1:0),s=1;s{try{a.apply(this,o)}catch(d){console.error(d)}})}removeListener(t,n){let o=this._getHandlersByEventName(t),s=o.indexOf(n);s>-1&&o.splice(s,1)}removeAllListeners(t){this.events[t]!==void 0&&(this.events[t].length=0)}reset(){this.events={}}};w.eventEmitter=new Qe;var Qr=(e,t)=>{w.eventEmitter.on(e,t)},es=(e,t)=>{w.eventEmitter.once(e,t)},ts=(e,t)=>{if(!e){w.eventEmitter.reset();return}t?w.eventEmitter.removeListener(e,t):w.eventEmitter.removeAllListeners(e)},ns=Object.freeze({__proto__:null,argsToParams:Wr,bindClickHandler:Zr,clickCancel:Wo,clickConfirm:Qt,clickDeny:jo,enableLoading:re,fire:Yr,getActions:be,getCancelButton:ae,getCloseButton:at,getConfirmButton:R,getContainer:B,getDenyButton:ee,getFocusableElements:it,getFooter:qt,getHtmlContainer:rt,getIcon:se,getIconContent:Kn,getImage:zt,getInputLabel:Xn,getLoader:ie,getPopup:y,getProgressSteps:st,getTimerLeft:Ur,getTimerProgressBar:ze,getTitle:Rt,getValidationMessage:Re,increaseTimer:Kr,isDeprecatedParameter:kn,isLoading:Jn,isTimerRunning:Xr,isUpdatableParameter:vn,isValidParameter:bn,isVisible:Fo,mixin:Vr,off:ts,on:Qr,once:es,resumeTimer:An,showLoading:re,stopTimer:Pn,toggleTimer:Gr}),et=class{constructor(t,n){this.callback=t,this.remaining=n,this.running=!1,this.start()}start(){return this.running||(this.running=!0,this.started=new Date,this.id=setTimeout(this.callback,this.remaining)),this.remaining}stop(){return this.started&&this.running&&(this.running=!1,clearTimeout(this.id),this.remaining-=new Date().getTime()-this.started.getTime()),this.remaining}increase(t){let n=this.running;return n&&this.stop(),this.remaining+=t,n&&this.start(),this.remaining}getTimerLeft(){return this.running&&(this.stop(),this.start()),this.remaining}isRunning(){return this.running}},In=["swal-title","swal-html","swal-footer"],os=e=>{let t=typeof e.template=="string"?document.querySelector(e.template):e.template;if(!t)return{};let n=t.content;return ds(n),Object.assign(rs(n),ss(n),as(n),is(n),ls(n),cs(n),us(n,In))},rs=e=>{let t={};return Array.from(e.querySelectorAll("swal-param")).forEach(o=>{Z(o,["name","value"]);let s=o.getAttribute("name"),a=o.getAttribute("value");!s||!a||(typeof ne[s]=="boolean"?t[s]=a!=="false":typeof ne[s]=="object"?t[s]=JSON.parse(a):t[s]=a)}),t},ss=e=>{let t={};return Array.from(e.querySelectorAll("swal-function-param")).forEach(o=>{let s=o.getAttribute("name"),a=o.getAttribute("value");!s||!a||(t[s]=new Function(`return ${a}`)())}),t},as=e=>{let t={};return Array.from(e.querySelectorAll("swal-button")).forEach(o=>{Z(o,["type","color","aria-label"]);let s=o.getAttribute("type");!s||!["confirm","cancel","deny"].includes(s)||(t[`${s}ButtonText`]=o.innerHTML,t[`show${tt(s)}Button`]=!0,o.hasAttribute("color")&&(t[`${s}ButtonColor`]=o.getAttribute("color")),o.hasAttribute("aria-label")&&(t[`${s}ButtonAriaLabel`]=o.getAttribute("aria-label")))}),t},is=e=>{let t={},n=e.querySelector("swal-image");return n&&(Z(n,["src","width","height","alt"]),n.hasAttribute("src")&&(t.imageUrl=n.getAttribute("src")||void 0),n.hasAttribute("width")&&(t.imageWidth=n.getAttribute("width")||void 0),n.hasAttribute("height")&&(t.imageHeight=n.getAttribute("height")||void 0),n.hasAttribute("alt")&&(t.imageAlt=n.getAttribute("alt")||void 0)),t},ls=e=>{let t={},n=e.querySelector("swal-icon");return n&&(Z(n,["type","color"]),n.hasAttribute("type")&&(t.icon=n.getAttribute("type")),n.hasAttribute("color")&&(t.iconColor=n.getAttribute("color")),t.iconHtml=n.innerHTML),t},cs=e=>{let t={},n=e.querySelector("swal-input");n&&(Z(n,["type","label","placeholder","value"]),t.input=n.getAttribute("type")||"text",n.hasAttribute("label")&&(t.inputLabel=n.getAttribute("label")),n.hasAttribute("placeholder")&&(t.inputPlaceholder=n.getAttribute("placeholder")),n.hasAttribute("value")&&(t.inputValue=n.getAttribute("value")));let o=Array.from(e.querySelectorAll("swal-input-option"));return o.length&&(t.inputOptions={},o.forEach(s=>{Z(s,["value"]);let a=s.getAttribute("value");if(!a)return;let d=s.innerHTML;t.inputOptions[a]=d})),t},us=(e,t)=>{let n={};for(let o in t){let s=t[o],a=e.querySelector(s);a&&(Z(a,[]),n[s.replace(/^swal-/,"")]=a.innerHTML.trim())}return n},ds=e=>{let t=In.concat(["swal-param","swal-function-param","swal-button","swal-image","swal-icon","swal-input","swal-input-option"]);Array.from(e.children).forEach(n=>{let o=n.tagName.toLowerCase();t.includes(o)||D(`Unrecognized element <${o}>`)})},Z=(e,t)=>{Array.from(e.attributes).forEach(n=>{t.indexOf(n.name)===-1&&D([`Unrecognized attribute "${n.name}" on <${e.tagName.toLowerCase()}>.`,`${t.length?`Allowed attributes are: ${t.join(", ")}`:"To set the value, use HTML within the element."}`])})},Tn=10,ms=e=>{let t=B(),n=y();typeof e.willOpen=="function"&&e.willOpen(n),w.eventEmitter.emit("willOpen",n);let s=window.getComputedStyle(document.body).overflowY;ws(t,n,e),setTimeout(()=>{ps(t,n)},Tn),lt()&&(fs(t,e.scrollbarPadding,s),Jo()),!qe()&&!w.previousActiveElement&&(w.previousActiveElement=document.activeElement),typeof e.didOpen=="function"&&setTimeout(()=>e.didOpen(n)),w.eventEmitter.emit("didOpen",n),_(t,i["no-transition"])},_e=e=>{let t=y();if(e.target!==t)return;let n=B();t.removeEventListener("animationend",_e),t.removeEventListener("transitionend",_e),n.style.overflowY="auto"},ps=(e,t)=>{Wt(t)?(e.style.overflowY="hidden",t.addEventListener("animationend",_e),t.addEventListener("transitionend",_e)):e.style.overflowY="auto"},fs=(e,t,n)=>{Qo(),t&&n!=="hidden"&&ar(n),setTimeout(()=>{e.scrollTop=0})},ws=(e,t,n)=>{h(e,n.showClass.backdrop),n.animation?(t.style.setProperty("opacity","0","important"),A(t,"grid"),setTimeout(()=>{h(t,n.showClass.popup),t.style.removeProperty("opacity")},Tn)):A(t,"grid"),h([document.documentElement,document.body],i.shown),n.heightAuto&&n.backdrop&&!n.toast&&h([document.documentElement,document.body],i["height-auto"])},$t={email:(e,t)=>/^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(e)?Promise.resolve():Promise.resolve(t||"Invalid email address"),url:(e,t)=>/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-z]{2,63}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/.test(e)?Promise.resolve():Promise.resolve(t||"Invalid URL")};function gs(e){e.inputValidator||(e.input==="email"&&(e.inputValidator=$t.email),e.input==="url"&&(e.inputValidator=$t.url))}function hs(e){(!e.target||typeof e.target=="string"&&!document.querySelector(e.target)||typeof e.target!="string"&&!e.target.appendChild)&&(D('Target parameter is not valid, defaulting to "body"'),e.target="body")}function ys(e){gs(e),e.showLoaderOnConfirm&&!e.preConfirm&&D(`showLoaderOnConfirm is set to true, but preConfirm is not defined. showLoaderOnConfirm should be used together with preConfirm, see usage example: -https://sweetalert2.github.io/#ajax-request`),bs(e),typeof e.title=="string"&&(e.title=e.title.split(` -`).join("
        ")),po(e)}var R,Te=new WeakMap,x=class{constructor(){if(jn(this,Te,void 0),typeof window>"u")return;R=this;for(var t=arguments.length,n=new Array(t),o=0;o1&&arguments[1]!==void 0?arguments[1]:{};if(xn(Object.assign({},n,t)),w.currentInstance){let a=re.swalPromiseResolve.get(w.currentInstance),{isAwaitingPromise:d}=w.currentInstance;w.currentInstance._destroy(),d||a({isDismissed:!0}),ct()&&on()}w.currentInstance=R;let o=Cs(t,n);vs(o),Object.freeze(o),w.timeout&&(w.timeout.stop(),delete w.timeout),clearTimeout(w.restoreFocusTimeout);let s=xs(R);return Qt(R,o),v.innerParams.set(R,o),ks(R,s,o)}then(t){return Et(Te,this).then(t)}finally(t){return Et(Te,this).finally(t)}},ks=(e,t,n)=>new Promise((o,s)=>{let a=d=>{e.close({isDismissed:!0,dismiss:d})};re.swalPromiseResolve.set(e,o),re.swalPromiseReject.set(e,s),t.confirmButton.onclick=()=>{Sr(e)},t.denyButton.onclick=()=>{Pr(e)},t.cancelButton.onclick=()=>{Ar(e,a)},t.closeButton.onclick=()=>{a(ce.close)},Rr(n,t,a),Uo(w,n,a),gr(e,n),fs(n),Es(w,n,a),Ss(t,n),setTimeout(()=>{t.container.scrollTop=0})}),Cs=(e,t)=>{let n=ss(e),o=Object.assign({},oe,t,n,e);return o.showClass=Object.assign({},oe.showClass,o.showClass),o.hideClass=Object.assign({},oe.hideClass,o.hideClass),o.animation===!1&&(o.showClass={backdrop:"swal2-noanimation"},o.hideClass={}),o},xs=e=>{let t={popup:y(),container:L(),actions:ve(),confirmButton:z(),denyButton:te(),cancelButton:ie(),loader:le(),closeButton:it(),validationMessage:ze(),progressSteps:at()};return v.domCache.set(e,t),t},Es=(e,t,n)=>{let o=qe();D(o),t.timer&&(e.timeout=new tt(()=>{n("timer"),delete e.timeout},t.timer),t.timerProgressBar&&(A(o),O(o,t,"timerProgressBar"),setTimeout(()=>{e.timeout&&e.timeout.running&&dt(t.timer)})))},Ss=(e,t)=>{if(!t.toast){if(!Re(t.allowEnterKey)){Rt("allowEnterKey"),Is();return}Ps(e)||As(e,t)||Je(-1,1)}},Ps=e=>{let t=Array.from(e.popup.querySelectorAll("[autofocus]"));for(let n of t)if(n instanceof HTMLElement&&M(n))return n.focus(),!0;return!1},As=(e,t)=>t.focusDeny&&M(e.denyButton)?(e.denyButton.focus(),!0):t.focusCancel&&M(e.cancelButton)?(e.cancelButton.focus(),!0):t.focusConfirm&&M(e.confirmButton)?(e.confirmButton.focus(),!0):!1,Is=()=>{document.activeElement instanceof HTMLElement&&typeof document.activeElement.blur=="function"&&document.activeElement.blur()};x.prototype.disableButtons=wn;x.prototype.enableButtons=fn;x.prototype.getInput=dn;x.prototype.disableInput=hn;x.prototype.enableInput=gn;x.prototype.hideLoading=He;x.prototype.disableLoading=He;x.prototype.showValidationMessage=yn;x.prototype.resetValidationMessage=bn;x.prototype.close=G;x.prototype.closePopup=G;x.prototype.closeModal=G;x.prototype.closeToast=G;x.prototype.rejectPromise=an;x.prototype.update=En;x.prototype._destroy=Sn;Object.assign(x,rs);Object.keys(Nr).forEach(e=>{x[e]=function(){return R&&R[e]?R[e](...arguments):null}});x.DismissReason=ce;x.version="11.18.0";var Q=x;Q.default=Q;typeof document<"u"&&(function(e,t){var n=e.createElement("style");if(e.getElementsByTagName("head")[0].appendChild(n),n.styleSheet)n.styleSheet.disabled||(n.styleSheet.cssText=t);else try{n.innerHTML=t}catch{n.innerText=t}})(document,':root{--swal2-container-padding: 0.625em;--swal2-backdrop: rgba(0, 0, 0, 0.4);--swal2-width: 32em;--swal2-padding: 0 0 1.25em;--swal2-border: none;--swal2-border-radius: 0.3125rem;--swal2-background: white;--swal2-color: #545454;--swal2-footer-border-color: #eee;--swal2-show-animation: swal2-show 0.3s;--swal2-hide-animation: swal2-hide 0.15s forwards;--swal2-title-padding: 0.8em 1em 0;--swal2-html-container-padding: 1em 1.6em 0.3em;--swal2-input-background: transparent;--swal2-progress-step-background: #add8e6;--swal2-validation-message-background: #f0f0f0;--swal2-validation-message-color: #666;--swal2-close-button-position: initial;--swal2-close-button-inset: auto;--swal2-close-button-font-size: 2.5em;--swal2-close-button-color: #ccc;--swal2-close-button-transition: color 0.1s, box-shadow 0.1s;--swal2-close-button-outline: initial;--swal2-close-button-hover-transform: none}[data-swal2-theme=dark]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white)}@media(prefers-color-scheme: dark){[data-swal2-theme=auto]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white)}}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto !important}body.swal2-no-backdrop .swal2-container{background-color:rgba(0,0,0,0) !important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:all}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px var(--swal2-backdrop)}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:rgba(0,0,0,0);pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{inset:0 auto auto 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{inset:0 0 auto auto}body.swal2-toast-shown .swal2-container.swal2-top-start,body.swal2-toast-shown .swal2-container.swal2-top-left{inset:0 auto auto 0}body.swal2-toast-shown .swal2-container.swal2-center-start,body.swal2-toast-shown .swal2-container.swal2-center-left{inset:50% auto auto 0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{inset:50% auto auto 50%;transform:translate(-50%, -50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{inset:50% 0 auto auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-start,body.swal2-toast-shown .swal2-container.swal2-bottom-left{inset:auto auto 0 0}body.swal2-toast-shown .swal2-container.swal2-bottom{inset:auto auto 0 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{inset:auto 0 0 auto}@media print{body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow-y:scroll !important}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown) .swal2-container{position:static !important}}div:where(.swal2-container){display:grid;position:fixed;z-index:1060;inset:0;box-sizing:border-box;grid-template-areas:"top-start top top-end" "center-start center center-end" "bottom-start bottom-center bottom-end";grid-template-rows:minmax(min-content, auto) minmax(min-content, auto) minmax(min-content, auto);height:100%;padding:var(--swal2-container-padding);overflow-x:hidden;transition:background-color .1s;-webkit-overflow-scrolling:touch}div:where(.swal2-container).swal2-backdrop-show,div:where(.swal2-container).swal2-noanimation{background:var(--swal2-backdrop)}div:where(.swal2-container).swal2-backdrop-hide{background:rgba(0,0,0,0) !important}div:where(.swal2-container).swal2-top-start,div:where(.swal2-container).swal2-center-start,div:where(.swal2-container).swal2-bottom-start{grid-template-columns:minmax(0, 1fr) auto auto}div:where(.swal2-container).swal2-top,div:where(.swal2-container).swal2-center,div:where(.swal2-container).swal2-bottom{grid-template-columns:auto minmax(0, 1fr) auto}div:where(.swal2-container).swal2-top-end,div:where(.swal2-container).swal2-center-end,div:where(.swal2-container).swal2-bottom-end{grid-template-columns:auto auto minmax(0, 1fr)}div:where(.swal2-container).swal2-top-start>.swal2-popup{align-self:start}div:where(.swal2-container).swal2-top>.swal2-popup{grid-column:2;place-self:start center}div:where(.swal2-container).swal2-top-end>.swal2-popup,div:where(.swal2-container).swal2-top-right>.swal2-popup{grid-column:3;place-self:start end}div:where(.swal2-container).swal2-center-start>.swal2-popup,div:where(.swal2-container).swal2-center-left>.swal2-popup{grid-row:2;align-self:center}div:where(.swal2-container).swal2-center>.swal2-popup{grid-column:2;grid-row:2;place-self:center center}div:where(.swal2-container).swal2-center-end>.swal2-popup,div:where(.swal2-container).swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;place-self:center end}div:where(.swal2-container).swal2-bottom-start>.swal2-popup,div:where(.swal2-container).swal2-bottom-left>.swal2-popup{grid-column:1;grid-row:3;align-self:end}div:where(.swal2-container).swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;place-self:end center}div:where(.swal2-container).swal2-bottom-end>.swal2-popup,div:where(.swal2-container).swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;place-self:end end}div:where(.swal2-container).swal2-grow-row>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-column:1/4;width:100%}div:where(.swal2-container).swal2-grow-column>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}div:where(.swal2-container).swal2-no-transition{transition:none !important}div:where(.swal2-container) div:where(.swal2-popup){display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0, 100%);width:var(--swal2-width);max-width:100%;padding:var(--swal2-padding);border:var(--swal2-border);border-radius:var(--swal2-border-radius);background:var(--swal2-background);color:var(--swal2-color);font-family:inherit;font-size:1rem}div:where(.swal2-container) div:where(.swal2-popup):focus{outline:none}div:where(.swal2-container) div:where(.swal2-popup).swal2-loading{overflow-y:hidden}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable{cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable div:where(.swal2-icon){cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging{cursor:grabbing}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging div:where(.swal2-icon){cursor:grabbing}div:where(.swal2-container) h2:where(.swal2-title){position:relative;max-width:100%;margin:0;padding:var(--swal2-title-padding);color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;word-wrap:break-word;cursor:initial}div:where(.swal2-container) div:where(.swal2-actions){display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:center;width:auto;margin:1.25em auto 0;padding:0}div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled[disabled]{opacity:.4}div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled:hover{background-image:linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1))}div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled:active{background-image:linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2))}div:where(.swal2-container) div:where(.swal2-loader){display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 rgba(0,0,0,0) #2778c4 rgba(0,0,0,0)}div:where(.swal2-container) button:where(.swal2-styled){margin:.3125em;padding:.625em 1.1em;transition:box-shadow .1s;box-shadow:0 0 0 3px rgba(0,0,0,0);font-weight:500}div:where(.swal2-container) button:where(.swal2-styled):not([disabled]){cursor:pointer}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm){border:0;border-radius:.25em;background:initial;background-color:#7066e0;color:#fff;font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):focus-visible{box-shadow:0 0 0 3px rgba(112,102,224,.5)}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny){border:0;border-radius:.25em;background:initial;background-color:#dc3741;color:#fff;font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):focus-visible{box-shadow:0 0 0 3px rgba(220,55,65,.5)}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel){border:0;border-radius:.25em;background:initial;background-color:#6e7881;color:#fff;font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):focus-visible{box-shadow:0 0 0 3px rgba(110,120,129,.5)}div:where(.swal2-container) button:where(.swal2-styled).swal2-default-outline:focus-visible{box-shadow:0 0 0 3px rgba(100,150,200,.5)}div:where(.swal2-container) button:where(.swal2-styled):focus-visible{outline:none}div:where(.swal2-container) button:where(.swal2-styled)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-footer){margin:1em 0 0;padding:1em 1em 0;border-top:1px solid var(--swal2-footer-border-color);color:inherit;font-size:1em;text-align:center;cursor:initial}div:where(.swal2-container) .swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto !important;overflow:hidden;border-bottom-right-radius:var(--swal2-border-radius);border-bottom-left-radius:var(--swal2-border-radius)}div:where(.swal2-container) div:where(.swal2-timer-progress-bar){width:100%;height:.25em;background:rgba(0,0,0,.2)}div:where(.swal2-container) img:where(.swal2-image){max-width:100%;margin:2em auto 1em;cursor:initial}div:where(.swal2-container) button:where(.swal2-close){position:var(--swal2-close-button-position);inset:var(--swal2-close-button-inset);z-index:2;align-items:center;justify-content:center;width:1.2em;height:1.2em;margin-top:0;margin-right:0;margin-bottom:-1.2em;padding:0;overflow:hidden;transition:var(--swal2-close-button-transition);border:none;border-radius:var(--swal2-border-radius);outline:var(--swal2-close-button-outline);background:rgba(0,0,0,0);color:var(--swal2-close-button-color);font-family:monospace;font-size:var(--swal2-close-button-font-size);cursor:pointer;justify-self:end}div:where(.swal2-container) button:where(.swal2-close):hover{transform:var(--swal2-close-button-hover-transform);background:rgba(0,0,0,0);color:#f27474}div:where(.swal2-container) button:where(.swal2-close):focus-visible{outline:none;box-shadow:inset 0 0 0 3px rgba(100,150,200,.5)}div:where(.swal2-container) button:where(.swal2-close)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-html-container){z-index:1;justify-content:center;margin:0;padding:var(--swal2-html-container-padding);overflow:auto;color:inherit;font-size:1.125em;font-weight:normal;line-height:normal;text-align:center;word-wrap:break-word;word-break:break-word;cursor:initial}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea),div:where(.swal2-container) select:where(.swal2-select),div:where(.swal2-container) div:where(.swal2-radio),div:where(.swal2-container) label:where(.swal2-checkbox){margin:1em 2em 3px}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea){box-sizing:border-box;width:auto;transition:border-color .1s,box-shadow .1s;border:1px solid #d9d9d9;border-radius:.1875em;background:var(--swal2-input-background);box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px rgba(0,0,0,0);color:inherit;font-size:1.125em}div:where(.swal2-container) input:where(.swal2-input).swal2-inputerror,div:where(.swal2-container) input:where(.swal2-file).swal2-inputerror,div:where(.swal2-container) textarea:where(.swal2-textarea).swal2-inputerror{border-color:#f27474 !important;box-shadow:0 0 2px #f27474 !important}div:where(.swal2-container) input:where(.swal2-input):focus,div:where(.swal2-container) input:where(.swal2-file):focus,div:where(.swal2-container) textarea:where(.swal2-textarea):focus{border:1px solid #b4dbed;outline:none;box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px rgba(100,150,200,.5)}div:where(.swal2-container) input:where(.swal2-input)::placeholder,div:where(.swal2-container) input:where(.swal2-file)::placeholder,div:where(.swal2-container) textarea:where(.swal2-textarea)::placeholder{color:#ccc}div:where(.swal2-container) .swal2-range{margin:1em 2em 3px;background:var(--swal2-background)}div:where(.swal2-container) .swal2-range input{width:80%}div:where(.swal2-container) .swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}div:where(.swal2-container) .swal2-range input,div:where(.swal2-container) .swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}div:where(.swal2-container) .swal2-input{height:2.625em;padding:0 .75em}div:where(.swal2-container) .swal2-file{width:75%;margin-right:auto;margin-left:auto;background:var(--swal2-input-background);font-size:1.125em}div:where(.swal2-container) .swal2-textarea{height:6.75em;padding:.75em}div:where(.swal2-container) .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:var(--swal2-input-background);color:inherit;font-size:1.125em}div:where(.swal2-container) .swal2-radio,div:where(.swal2-container) .swal2-checkbox{align-items:center;justify-content:center;background:var(--swal2-background);color:inherit}div:where(.swal2-container) .swal2-radio label,div:where(.swal2-container) .swal2-checkbox label{margin:0 .6em;font-size:1.125em}div:where(.swal2-container) .swal2-radio input,div:where(.swal2-container) .swal2-checkbox input{flex-shrink:0;margin:0 .4em}div:where(.swal2-container) label:where(.swal2-input-label){display:flex;justify-content:center;margin:1em auto 0}div:where(.swal2-container) div:where(.swal2-validation-message){align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:var(--swal2-validation-message-background);color:var(--swal2-validation-message-color);font-size:1em;font-weight:300}div:where(.swal2-container) div:where(.swal2-validation-message)::before{content:"!";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}div:where(.swal2-container) .swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:rgba(0,0,0,0);font-weight:600}div:where(.swal2-container) .swal2-progress-steps li{display:inline-block;position:relative}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:var(--swal2-progress-step-background);color:#fff}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:var(--swal2-progress-step-background)}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}div:where(.swal2-icon){position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;border:.25em solid rgba(0,0,0,0);border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;user-select:none}div:where(.swal2-icon) .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}div:where(.swal2-icon).swal2-error{border-color:#f27474;color:#f27474}div:where(.swal2-icon).swal2-error .swal2-x-mark{position:relative;flex-grow:1}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}div:where(.swal2-icon).swal2-warning{border-color:#f8bb86;color:#f8bb86}div:where(.swal2-icon).swal2-warning.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-warning.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .5s}div:where(.swal2-icon).swal2-info{border-color:#3fc3ee;color:#3fc3ee}div:where(.swal2-icon).swal2-info.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-info.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .8s}div:where(.swal2-icon).swal2-question{border-color:#87adbd;color:#87adbd}div:where(.swal2-icon).swal2-question.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-question.swal2-icon-show .swal2-icon-content{animation:swal2-animate-question-mark .8s}div:where(.swal2-icon).swal2-success{border-color:#a5dc86;color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;border-radius:50%}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}div:where(.swal2-icon).swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-0.25em;left:-0.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}div:where(.swal2-icon).swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}[class^=swal2]{-webkit-tap-highlight-color:rgba(0,0,0,0)}.swal2-show{animation:var(--swal2-show-animation)}.swal2-hide{animation:var(--swal2-hide-animation)}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{margin-right:initial;margin-left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}.swal2-toast{box-sizing:border-box;grid-column:1/4 !important;grid-row:1/4 !important;grid-template-columns:min-content auto min-content;padding:1em;overflow-y:hidden;background:var(--swal2-background);box-shadow:0 0 1px rgba(0,0,0,.075),0 1px 2px rgba(0,0,0,.075),1px 2px 4px rgba(0,0,0,.075),1px 3px 8px rgba(0,0,0,.075),2px 4px 16px rgba(0,0,0,.075);pointer-events:all}.swal2-toast>*{grid-column:2}.swal2-toast h2:where(.swal2-title){margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-toast .swal2-loading{justify-content:center}.swal2-toast input:where(.swal2-input){height:2em;margin:.5em;font-size:1em}.swal2-toast .swal2-validation-message{font-size:1em}.swal2-toast div:where(.swal2-footer){margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-toast button:where(.swal2-close){grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-toast div:where(.swal2-html-container){margin:.5em 1em;padding:0;overflow:initial;font-size:1em;text-align:initial}.swal2-toast div:where(.swal2-html-container):empty{padding:0}.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-toast .swal2-icon{grid-column:1;grid-row:1/99;align-self:center;width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:bold}.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-toast div:where(.swal2-actions){justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-toast button:where(.swal2-styled){margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;border-radius:50%}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.8em;left:-0.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}.swal2-toast.swal2-show{animation:swal2-toast-show .5s}.swal2-toast.swal2-hide{animation:swal2-toast-hide .1s forwards}@keyframes swal2-show{0%{transform:scale(0.7)}45%{transform:scale(1.05)}80%{transform:scale(0.95)}100%{transform:scale(1)}}@keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(0.5);opacity:0}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-0.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(0.4);opacity:0}50%{margin-top:1.625em;transform:scale(0.4);opacity:0}80%{margin-top:-0.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);opacity:1}}@keyframes swal2-rotate-loading{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}25%{transform:rotateZ(-25deg);opacity:.4}50%{transform:rotateZ(15deg);opacity:.8}75%{transform:rotateZ(-5deg);opacity:1}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-toast-show{0%{transform:translateY(-0.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(0.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0deg)}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-0.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}');var de=document.createElement("div"),We=document.getElementById("game-wrapper");document.getElementById("origin-menu")?.remove();document.getElementById("origin-toggler")?.remove();de.id="origin-menu";de.style="position: fixed;top: -10%;left: 10%;right: 10%;width: 80%;height: 80%;z-index: 2;background-color: rgba(0, 0, 0, 0.5);backdrop-filter: blur(5px);";We?.prepend(de);var ue=document.createElement("button");ue.id="origin-toggler";var ht=!1;We?.prepend(ue);ue.onclick=()=>{ht=!ht,ht?(ue.innerText="▼",de.style.top="-100vh"):(ue.innerText="▲",de.style.top="10%")};ue.onclick({});var pe=document.createElement("DIV");pe.classList.add("menu-left");de.append(pe);var Bn=!0;function q(e){let t=document.createElement("div");Bn==!1?(t.append(document.createElement("br")),t.append(document.createElement("br"))):Bn=!1,t.classList.add("menu-area"),t.style.textAlign="center",pe.append(t);let n=document.createElement("h1");return n.innerText=e,n.style.textAlign="center",n.style.color="white",t.append(n),t}var Ye=document.createElement("h1");Ye.classList.add("menu-title");Ye.innerText="Play Origin";Ye.style.textAlign="center";pe.append(Ye);var Ve=document.createElement("h2");Ve.style.fontSize="25px";Ve.style.color="white";Ve.innerHTML="
        Press SHIFT to show/hide the menu. Scroll down in the menu for more mods.";pe.append(Ve);var Ue=document.createElement("h3");Ue.style.fontSize="20px";Ue.innerHTML=` +https://sweetalert2.github.io/#ajax-request`),hs(e),typeof e.title=="string"&&(e.title=e.title.split(` +`).join("
        ")),co(e)}var N,Ie=new WeakMap,x=class{constructor(){if(qn(this,Ie,void 0),typeof window>"u")return;N=this;for(var t=arguments.length,n=new Array(t),o=0;o1&&arguments[1]!==void 0?arguments[1]:{};if(Cn(Object.assign({},n,t)),w.currentInstance){let a=oe.swalPromiseResolve.get(w.currentInstance),{isAwaitingPromise:d}=w.currentInstance;w.currentInstance._destroy(),d||a({isDismissed:!0}),lt()&&nn()}w.currentInstance=N;let o=vs(t,n);ys(o),Object.freeze(o),w.timeout&&(w.timeout.stop(),delete w.timeout),clearTimeout(w.restoreFocusTimeout);let s=ks(N);return Jt(N,o),v.innerParams.set(N,o),bs(N,s,o)}then(t){return xt(Ie,this).then(t)}finally(t){return xt(Ie,this).finally(t)}},bs=(e,t,n)=>new Promise((o,s)=>{let a=d=>{e.close({isDismissed:!0,dismiss:d})};oe.swalPromiseResolve.set(e,o),oe.swalPromiseReject.set(e,s),t.confirmButton.onclick=()=>{xr(e)},t.denyButton.onclick=()=>{Er(e)},t.cancelButton.onclick=()=>{Sr(e,a)},t.closeButton.onclick=()=>{a(le.close)},_r(n,t,a),Yo(w,n,a),fr(e,n),ms(n),Cs(w,n,a),xs(t,n),setTimeout(()=>{t.container.scrollTop=0})}),vs=(e,t)=>{let n=os(e),o=Object.assign({},ne,t,n,e);return o.showClass=Object.assign({},ne.showClass,o.showClass),o.hideClass=Object.assign({},ne.hideClass,o.hideClass),o.animation===!1&&(o.showClass={backdrop:"swal2-noanimation"},o.hideClass={}),o},ks=e=>{let t={popup:y(),container:B(),actions:be(),confirmButton:R(),denyButton:ee(),cancelButton:ae(),loader:ie(),closeButton:at(),validationMessage:Re(),progressSteps:st()};return v.domCache.set(e,t),t},Cs=(e,t,n)=>{let o=ze();T(o),t.timer&&(e.timeout=new et(()=>{n("timer"),delete e.timeout},t.timer),t.timerProgressBar&&(A(o),$(o,t,"timerProgressBar"),setTimeout(()=>{e.timeout&&e.timeout.running&&ut(t.timer)})))},xs=(e,t)=>{if(!t.toast){if(!Ne(t.allowEnterKey)){Nt("allowEnterKey"),Ps();return}Es(e)||Ss(e,t)||Ze(-1,1)}},Es=e=>{let t=Array.from(e.popup.querySelectorAll("[autofocus]"));for(let n of t)if(n instanceof HTMLElement&&L(n))return n.focus(),!0;return!1},Ss=(e,t)=>t.focusDeny&&L(e.denyButton)?(e.denyButton.focus(),!0):t.focusCancel&&L(e.cancelButton)?(e.cancelButton.focus(),!0):t.focusConfirm&&L(e.confirmButton)?(e.confirmButton.focus(),!0):!1,Ps=()=>{document.activeElement instanceof HTMLElement&&typeof document.activeElement.blur=="function"&&document.activeElement.blur()};x.prototype.disableButtons=fn;x.prototype.enableButtons=pn;x.prototype.getInput=un;x.prototype.disableInput=gn;x.prototype.enableInput=wn;x.prototype.hideLoading=Oe;x.prototype.disableLoading=Oe;x.prototype.showValidationMessage=hn;x.prototype.resetValidationMessage=yn;x.prototype.close=U;x.prototype.closePopup=U;x.prototype.closeModal=U;x.prototype.closeToast=U;x.prototype.rejectPromise=sn;x.prototype.update=xn;x.prototype._destroy=En;Object.assign(x,ns);Object.keys(Hr).forEach(e=>{x[e]=function(){return N&&N[e]?N[e](...arguments):null}});x.DismissReason=le;x.version="11.18.0";var J=x;J.default=J;typeof document<"u"&&(function(e,t){var n=e.createElement("style");if(e.getElementsByTagName("head")[0].appendChild(n),n.styleSheet)n.styleSheet.disabled||(n.styleSheet.cssText=t);else try{n.innerHTML=t}catch{n.innerText=t}})(document,':root{--swal2-container-padding: 0.625em;--swal2-backdrop: rgba(0, 0, 0, 0.4);--swal2-width: 32em;--swal2-padding: 0 0 1.25em;--swal2-border: none;--swal2-border-radius: 0.3125rem;--swal2-background: white;--swal2-color: #545454;--swal2-footer-border-color: #eee;--swal2-show-animation: swal2-show 0.3s;--swal2-hide-animation: swal2-hide 0.15s forwards;--swal2-title-padding: 0.8em 1em 0;--swal2-html-container-padding: 1em 1.6em 0.3em;--swal2-input-background: transparent;--swal2-progress-step-background: #add8e6;--swal2-validation-message-background: #f0f0f0;--swal2-validation-message-color: #666;--swal2-close-button-position: initial;--swal2-close-button-inset: auto;--swal2-close-button-font-size: 2.5em;--swal2-close-button-color: #ccc;--swal2-close-button-transition: color 0.1s, box-shadow 0.1s;--swal2-close-button-outline: initial;--swal2-close-button-hover-transform: none}[data-swal2-theme=dark]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white)}@media(prefers-color-scheme: dark){[data-swal2-theme=auto]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white)}}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto !important}body.swal2-no-backdrop .swal2-container{background-color:rgba(0,0,0,0) !important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:all}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px var(--swal2-backdrop)}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:rgba(0,0,0,0);pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{inset:0 auto auto 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{inset:0 0 auto auto}body.swal2-toast-shown .swal2-container.swal2-top-start,body.swal2-toast-shown .swal2-container.swal2-top-left{inset:0 auto auto 0}body.swal2-toast-shown .swal2-container.swal2-center-start,body.swal2-toast-shown .swal2-container.swal2-center-left{inset:50% auto auto 0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{inset:50% auto auto 50%;transform:translate(-50%, -50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{inset:50% 0 auto auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-start,body.swal2-toast-shown .swal2-container.swal2-bottom-left{inset:auto auto 0 0}body.swal2-toast-shown .swal2-container.swal2-bottom{inset:auto auto 0 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{inset:auto 0 0 auto}@media print{body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow-y:scroll !important}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown) .swal2-container{position:static !important}}div:where(.swal2-container){display:grid;position:fixed;z-index:1060;inset:0;box-sizing:border-box;grid-template-areas:"top-start top top-end" "center-start center center-end" "bottom-start bottom-center bottom-end";grid-template-rows:minmax(min-content, auto) minmax(min-content, auto) minmax(min-content, auto);height:100%;padding:var(--swal2-container-padding);overflow-x:hidden;transition:background-color .1s;-webkit-overflow-scrolling:touch}div:where(.swal2-container).swal2-backdrop-show,div:where(.swal2-container).swal2-noanimation{background:var(--swal2-backdrop)}div:where(.swal2-container).swal2-backdrop-hide{background:rgba(0,0,0,0) !important}div:where(.swal2-container).swal2-top-start,div:where(.swal2-container).swal2-center-start,div:where(.swal2-container).swal2-bottom-start{grid-template-columns:minmax(0, 1fr) auto auto}div:where(.swal2-container).swal2-top,div:where(.swal2-container).swal2-center,div:where(.swal2-container).swal2-bottom{grid-template-columns:auto minmax(0, 1fr) auto}div:where(.swal2-container).swal2-top-end,div:where(.swal2-container).swal2-center-end,div:where(.swal2-container).swal2-bottom-end{grid-template-columns:auto auto minmax(0, 1fr)}div:where(.swal2-container).swal2-top-start>.swal2-popup{align-self:start}div:where(.swal2-container).swal2-top>.swal2-popup{grid-column:2;place-self:start center}div:where(.swal2-container).swal2-top-end>.swal2-popup,div:where(.swal2-container).swal2-top-right>.swal2-popup{grid-column:3;place-self:start end}div:where(.swal2-container).swal2-center-start>.swal2-popup,div:where(.swal2-container).swal2-center-left>.swal2-popup{grid-row:2;align-self:center}div:where(.swal2-container).swal2-center>.swal2-popup{grid-column:2;grid-row:2;place-self:center center}div:where(.swal2-container).swal2-center-end>.swal2-popup,div:where(.swal2-container).swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;place-self:center end}div:where(.swal2-container).swal2-bottom-start>.swal2-popup,div:where(.swal2-container).swal2-bottom-left>.swal2-popup{grid-column:1;grid-row:3;align-self:end}div:where(.swal2-container).swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;place-self:end center}div:where(.swal2-container).swal2-bottom-end>.swal2-popup,div:where(.swal2-container).swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;place-self:end end}div:where(.swal2-container).swal2-grow-row>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-column:1/4;width:100%}div:where(.swal2-container).swal2-grow-column>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}div:where(.swal2-container).swal2-no-transition{transition:none !important}div:where(.swal2-container) div:where(.swal2-popup){display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0, 100%);width:var(--swal2-width);max-width:100%;padding:var(--swal2-padding);border:var(--swal2-border);border-radius:var(--swal2-border-radius);background:var(--swal2-background);color:var(--swal2-color);font-family:inherit;font-size:1rem}div:where(.swal2-container) div:where(.swal2-popup):focus{outline:none}div:where(.swal2-container) div:where(.swal2-popup).swal2-loading{overflow-y:hidden}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable{cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable div:where(.swal2-icon){cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging{cursor:grabbing}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging div:where(.swal2-icon){cursor:grabbing}div:where(.swal2-container) h2:where(.swal2-title){position:relative;max-width:100%;margin:0;padding:var(--swal2-title-padding);color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;word-wrap:break-word;cursor:initial}div:where(.swal2-container) div:where(.swal2-actions){display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:center;width:auto;margin:1.25em auto 0;padding:0}div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled[disabled]{opacity:.4}div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled:hover{background-image:linear-gradient(rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1))}div:where(.swal2-container) div:where(.swal2-actions):not(.swal2-loading) .swal2-styled:active{background-image:linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2))}div:where(.swal2-container) div:where(.swal2-loader){display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 rgba(0,0,0,0) #2778c4 rgba(0,0,0,0)}div:where(.swal2-container) button:where(.swal2-styled){margin:.3125em;padding:.625em 1.1em;transition:box-shadow .1s;box-shadow:0 0 0 3px rgba(0,0,0,0);font-weight:500}div:where(.swal2-container) button:where(.swal2-styled):not([disabled]){cursor:pointer}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm){border:0;border-radius:.25em;background:initial;background-color:#7066e0;color:#fff;font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):focus-visible{box-shadow:0 0 0 3px rgba(112,102,224,.5)}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny){border:0;border-radius:.25em;background:initial;background-color:#dc3741;color:#fff;font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):focus-visible{box-shadow:0 0 0 3px rgba(220,55,65,.5)}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel){border:0;border-radius:.25em;background:initial;background-color:#6e7881;color:#fff;font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):focus-visible{box-shadow:0 0 0 3px rgba(110,120,129,.5)}div:where(.swal2-container) button:where(.swal2-styled).swal2-default-outline:focus-visible{box-shadow:0 0 0 3px rgba(100,150,200,.5)}div:where(.swal2-container) button:where(.swal2-styled):focus-visible{outline:none}div:where(.swal2-container) button:where(.swal2-styled)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-footer){margin:1em 0 0;padding:1em 1em 0;border-top:1px solid var(--swal2-footer-border-color);color:inherit;font-size:1em;text-align:center;cursor:initial}div:where(.swal2-container) .swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto !important;overflow:hidden;border-bottom-right-radius:var(--swal2-border-radius);border-bottom-left-radius:var(--swal2-border-radius)}div:where(.swal2-container) div:where(.swal2-timer-progress-bar){width:100%;height:.25em;background:rgba(0,0,0,.2)}div:where(.swal2-container) img:where(.swal2-image){max-width:100%;margin:2em auto 1em;cursor:initial}div:where(.swal2-container) button:where(.swal2-close){position:var(--swal2-close-button-position);inset:var(--swal2-close-button-inset);z-index:2;align-items:center;justify-content:center;width:1.2em;height:1.2em;margin-top:0;margin-right:0;margin-bottom:-1.2em;padding:0;overflow:hidden;transition:var(--swal2-close-button-transition);border:none;border-radius:var(--swal2-border-radius);outline:var(--swal2-close-button-outline);background:rgba(0,0,0,0);color:var(--swal2-close-button-color);font-family:monospace;font-size:var(--swal2-close-button-font-size);cursor:pointer;justify-self:end}div:where(.swal2-container) button:where(.swal2-close):hover{transform:var(--swal2-close-button-hover-transform);background:rgba(0,0,0,0);color:#f27474}div:where(.swal2-container) button:where(.swal2-close):focus-visible{outline:none;box-shadow:inset 0 0 0 3px rgba(100,150,200,.5)}div:where(.swal2-container) button:where(.swal2-close)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-html-container){z-index:1;justify-content:center;margin:0;padding:var(--swal2-html-container-padding);overflow:auto;color:inherit;font-size:1.125em;font-weight:normal;line-height:normal;text-align:center;word-wrap:break-word;word-break:break-word;cursor:initial}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea),div:where(.swal2-container) select:where(.swal2-select),div:where(.swal2-container) div:where(.swal2-radio),div:where(.swal2-container) label:where(.swal2-checkbox){margin:1em 2em 3px}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea){box-sizing:border-box;width:auto;transition:border-color .1s,box-shadow .1s;border:1px solid #d9d9d9;border-radius:.1875em;background:var(--swal2-input-background);box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px rgba(0,0,0,0);color:inherit;font-size:1.125em}div:where(.swal2-container) input:where(.swal2-input).swal2-inputerror,div:where(.swal2-container) input:where(.swal2-file).swal2-inputerror,div:where(.swal2-container) textarea:where(.swal2-textarea).swal2-inputerror{border-color:#f27474 !important;box-shadow:0 0 2px #f27474 !important}div:where(.swal2-container) input:where(.swal2-input):focus,div:where(.swal2-container) input:where(.swal2-file):focus,div:where(.swal2-container) textarea:where(.swal2-textarea):focus{border:1px solid #b4dbed;outline:none;box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px rgba(100,150,200,.5)}div:where(.swal2-container) input:where(.swal2-input)::placeholder,div:where(.swal2-container) input:where(.swal2-file)::placeholder,div:where(.swal2-container) textarea:where(.swal2-textarea)::placeholder{color:#ccc}div:where(.swal2-container) .swal2-range{margin:1em 2em 3px;background:var(--swal2-background)}div:where(.swal2-container) .swal2-range input{width:80%}div:where(.swal2-container) .swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}div:where(.swal2-container) .swal2-range input,div:where(.swal2-container) .swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}div:where(.swal2-container) .swal2-input{height:2.625em;padding:0 .75em}div:where(.swal2-container) .swal2-file{width:75%;margin-right:auto;margin-left:auto;background:var(--swal2-input-background);font-size:1.125em}div:where(.swal2-container) .swal2-textarea{height:6.75em;padding:.75em}div:where(.swal2-container) .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:var(--swal2-input-background);color:inherit;font-size:1.125em}div:where(.swal2-container) .swal2-radio,div:where(.swal2-container) .swal2-checkbox{align-items:center;justify-content:center;background:var(--swal2-background);color:inherit}div:where(.swal2-container) .swal2-radio label,div:where(.swal2-container) .swal2-checkbox label{margin:0 .6em;font-size:1.125em}div:where(.swal2-container) .swal2-radio input,div:where(.swal2-container) .swal2-checkbox input{flex-shrink:0;margin:0 .4em}div:where(.swal2-container) label:where(.swal2-input-label){display:flex;justify-content:center;margin:1em auto 0}div:where(.swal2-container) div:where(.swal2-validation-message){align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:var(--swal2-validation-message-background);color:var(--swal2-validation-message-color);font-size:1em;font-weight:300}div:where(.swal2-container) div:where(.swal2-validation-message)::before{content:"!";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}div:where(.swal2-container) .swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:rgba(0,0,0,0);font-weight:600}div:where(.swal2-container) .swal2-progress-steps li{display:inline-block;position:relative}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:var(--swal2-progress-step-background);color:#fff}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:var(--swal2-progress-step-background)}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}div:where(.swal2-icon){position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;border:.25em solid rgba(0,0,0,0);border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;user-select:none}div:where(.swal2-icon) .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}div:where(.swal2-icon).swal2-error{border-color:#f27474;color:#f27474}div:where(.swal2-icon).swal2-error .swal2-x-mark{position:relative;flex-grow:1}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}div:where(.swal2-icon).swal2-warning{border-color:#f8bb86;color:#f8bb86}div:where(.swal2-icon).swal2-warning.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-warning.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .5s}div:where(.swal2-icon).swal2-info{border-color:#3fc3ee;color:#3fc3ee}div:where(.swal2-icon).swal2-info.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-info.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .8s}div:where(.swal2-icon).swal2-question{border-color:#87adbd;color:#87adbd}div:where(.swal2-icon).swal2-question.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-question.swal2-icon-show .swal2-icon-content{animation:swal2-animate-question-mark .8s}div:where(.swal2-icon).swal2-success{border-color:#a5dc86;color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;border-radius:50%}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}div:where(.swal2-icon).swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-0.25em;left:-0.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}div:where(.swal2-icon).swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}[class^=swal2]{-webkit-tap-highlight-color:rgba(0,0,0,0)}.swal2-show{animation:var(--swal2-show-animation)}.swal2-hide{animation:var(--swal2-hide-animation)}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{margin-right:initial;margin-left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}.swal2-toast{box-sizing:border-box;grid-column:1/4 !important;grid-row:1/4 !important;grid-template-columns:min-content auto min-content;padding:1em;overflow-y:hidden;background:var(--swal2-background);box-shadow:0 0 1px rgba(0,0,0,.075),0 1px 2px rgba(0,0,0,.075),1px 2px 4px rgba(0,0,0,.075),1px 3px 8px rgba(0,0,0,.075),2px 4px 16px rgba(0,0,0,.075);pointer-events:all}.swal2-toast>*{grid-column:2}.swal2-toast h2:where(.swal2-title){margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-toast .swal2-loading{justify-content:center}.swal2-toast input:where(.swal2-input){height:2em;margin:.5em;font-size:1em}.swal2-toast .swal2-validation-message{font-size:1em}.swal2-toast div:where(.swal2-footer){margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-toast button:where(.swal2-close){grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-toast div:where(.swal2-html-container){margin:.5em 1em;padding:0;overflow:initial;font-size:1em;text-align:initial}.swal2-toast div:where(.swal2-html-container):empty{padding:0}.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-toast .swal2-icon{grid-column:1;grid-row:1/99;align-self:center;width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:bold}.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-toast div:where(.swal2-actions){justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-toast button:where(.swal2-styled){margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;border-radius:50%}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.8em;left:-0.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}.swal2-toast.swal2-show{animation:swal2-toast-show .5s}.swal2-toast.swal2-hide{animation:swal2-toast-hide .1s forwards}@keyframes swal2-show{0%{transform:scale(0.7)}45%{transform:scale(1.05)}80%{transform:scale(0.95)}100%{transform:scale(1)}}@keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(0.5);opacity:0}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-0.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(0.4);opacity:0}50%{margin-top:1.625em;transform:scale(0.4);opacity:0}80%{margin-top:-0.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);opacity:1}}@keyframes swal2-rotate-loading{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}25%{transform:rotateZ(-25deg);opacity:.4}50%{transform:rotateZ(15deg);opacity:.8}75%{transform:rotateZ(-5deg);opacity:1}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-toast-show{0%{transform:translateY(-0.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(0.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0deg)}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-0.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}');var ue=document.createElement("div"),je=document.getElementById("game-wrapper");document.getElementById("origin-menu")?.remove();document.getElementById("origin-toggler")?.remove();ue.id="origin-menu";ue.style="position: fixed;top: -10%;left: 10%;right: 10%;width: 80%;height: 80%;z-index: 2;background-color: rgba(0, 0, 0, 0.5);backdrop-filter: blur(5px);";je?.prepend(ue);var ce=document.createElement("button");ce.id="origin-toggler";var gt=!1;je?.prepend(ce);ce.onclick=()=>{gt=!gt,gt?(ce.innerText="▼",ue.style.top="-100vh"):(ce.innerText="▲",ue.style.top="10%")};ce.onclick({});var de=document.createElement("DIV");de.classList.add("menu-left");ue.append(de);var Dn=!0;function z(e){let t=document.createElement("div");Dn==!1?(t.append(document.createElement("br")),t.append(document.createElement("br"))):Dn=!1,t.classList.add("menu-area"),t.style.textAlign="center",de.append(t);let n=document.createElement("h1");return n.innerText=e,n.style.textAlign="center",n.style.color="white",t.append(n),t}var We=document.createElement("h1");We.classList.add("menu-title");We.innerText="Play Origin";We.style.textAlign="center";de.append(We);var Ye=document.createElement("h2");Ye.style.fontSize="25px";Ye.style.color="white";Ye.innerHTML="
        Press SHIFT to show/hide the menu. Scroll down in the menu for more mods.";de.append(Ye);var Ve=document.createElement("h3");Ve.style.fontSize="20px";Ve.innerHTML=`

        Join our Discord https://dsc.gg/ProdigyPXP! ⭐ Rate 5 Stars


        -`;Ue.style.color="white";pe.append(Ue);var u={player:q("Player Mods"),inventory:q("Inventory Mods"),location:q("Location Mods"),pets:q("Pet Mods"),battle:q("Battle Mods"),battlepass:q("Battle Pass Mods"),minigames:q("Minigame Mods"),misc:q("Miscellaneous Mods"),utility:q("Utility Mods"),beta:q("Beta Testing | Beta Mods may damage your account")};localStorage.hasTip?console.log("Player already has tip."):((async()=>await Q.fire({title:"Welcome!",html:"To get started with the hacks, click this dropdown!",icon:"info"}))(),localStorage.hasTip=!0,console.log("Player was shown the tip."));localStorage.getItem("level")&&(c.player.getLevel=()=>localStorage.getItem("level"),console.log("Loaded menu from localStorage."));window.__ORIGIN_ABORT__?.abort();var Ln=new AbortController;window.__ORIGIN_ABORT__=Ln;var yt=!0;document.addEventListener("keydown",function(e){e.key=="Shift"&&(e.stopImmediatePropagation(),console.log("Shift key was pressed."),yt==!0?(console.log("Hiding mod menu..."),document.getElementById("origin-menu").style.display="none",document.getElementById("origin-toggler").style.display="none",yt=!1,console.log("Hidden mod menu.")):(console.log("Showing mod menu..."),document.getElementById("origin-menu").style.display="block",document.getElementById("origin-toggler").style.display="block",yt=!0,console.log("Shown mod menu.")))},{capture:!0,signal:Ln.signal});var p=class{constructor(t,n,o){this.parent=t;this.name="",this.description="",this.element=document.createElement("button"),this.element.classList.add("menu-hack"),this.parent.append(this.element),n&&this.setName(n),o&&this.setDesc(o)}parent;element;name;description;setName(t){return this.element.innerText=t,this.name=t,this}setClick(t){return this.element.onclick=async()=>{await t(),$(),console.log(`Triggered ${this.name}.`)},this}setDesc(t){return this.element.title=t,this.description=t,this}};var k=class extends p{constructor(n,o,s){super(n,o,s);this.parent=n;this.element.setAttribute("status","false"),this.migrateOldKey(),this.setClick(async()=>{this.status=!this.status,this.status?(localStorage.setItem(this.getStorageKey(),"true"),await this.enabled?.()):(localStorage.setItem(this.getStorageKey(),"false"),await this.disabled?.())})}parent;enabled;disabled;migrateOldKey(){let n=this.getStorageKey();this.name!==n&&localStorage.getItem(this.name)!==null&&(localStorage.setItem(n,localStorage.getItem(this.name)),localStorage.removeItem(this.name))}getStorageKey(){let n=this.parent.querySelector("h1")?.innerText??"";return n?`${n}::${this.name}`:this.name}get status(){return JSON.parse(this.element.getAttribute("status"))}set status(n){this.element.setAttribute("status",n.toString())}setEnabled(n){if(this.enabled=n,localStorage.getItem(this.getStorageKey())==="true")try{this.element.click()}catch(o){console.warn(`[Origin] Failed to restore toggle state for "${this.name}":`,o)}return this}setDisabled(n){return this.disabled=n,this}};var g=Q,K=g.mixin({input:"text",showCancelButton:!0,showConfirmButton:!0,toast:!1}),b=K.mixin({toast:!1,input:"number"}),l=g.mixin({toast:!0,position:"bottom"}),E=g.mixin({icon:"warning",showCancelButton:!0,toast:!1,confirmButtonText:"Confirm",cancelButtonText:"Cancel"}),Ys=g.mixin({icon:"info",showCancelButton:!1,toast:!1});window.Swal=g;function F(e,t){let n=c.constants;return!n||typeof n.set!="function"?!1:(n.set(e,t),!0)}new k(u.battle,"Instant Kill [PvE]","Makes your spells do insane damage in PvE!").setEnabled(async()=>(r.modifiers.damage=P,l.fire("Enabled!","You will now do insane damage in PvE!","success"))).setDisabled(()=>(r.modifiers.damage=1,l.fire("Disabled!","You will no longer do insane damage in PvE!","success")));new p(u.battle,"PvP Health [PvP]","Increases your HP in PvP by a hell ton.").setClick(async()=>(r.pvpHP=P,r.getMaxHearts=()=>P,l.fire("Success!","You now have lots of health!","success")));new p(u.battle,"Set Battle Hearts [PvP, PvE]","Sets your hearts in battle, automatically raise your max hearts in PvP or PvE.").setClick(async()=>{let e=await b.fire("Health Amount","How much HP do you want?","question");if(e.value!==void 0)return r.getMaxHearts=()=>+e.value,r.pvpHP=+e.value,r.data.hp=+e.value,l.fire("Success!","Your hearts have been set.","success")});new p(u.battle,"Fill Battle Energy [PvP, PvE]","Fills up your battle energy, if you are in PvP or PvE.").setClick(async()=>{let e=Ae.state.getCurrentState();return"teams"in e?(e.teams[0].setEnergy(99),l.fire("Success!","Your battle energy has been filled.","success")):l.fire("Error","You are currently not in a battle.","error")});new k(u.battle,"Disable math [PvP, PvE]","Disable math in PvP, PvE, anywhere! This doesn't work in the Floatling town.").setEnabled(async()=>F("GameConstants.Debug.EDUCATION_ENABLED",!1)?l.fire("Enabled!","You will no longer do Math!","success"):l.fire("Error","FlagProvider service not found.","error")).setDisabled(async()=>(F("GameConstants.Debug.EDUCATION_ENABLED",!0),l.fire("Disabled!","You will now do Math!","success")));new k(u.battle,"Skip enemy turn").setEnabled(async()=>F("GameConstants.Battle.SKIP_ENEMY_TURN",!0)?l.fire("Skipping!","Enemy turns will now be skipped.","success"):l.fire("Error","FlagProvider service not found.","error")).setDisabled(async()=>(F("GameConstants.Battle.SKIP_ENEMY_TURN",!1),l.fire("Disabled","Enemy turns will no longer be skipped.","success")));new p(u.battle,"Escape Battle [PvP, PvE]","Escape any battle, PvP or PvE!").setClick(async()=>{let e=Ae.state.current;if(e==="PVP")return Object.fromEntries(c.instance.game.state.states).PVP.endPVP(),l.fire("Escaped!","You have successfully escaped from the PvP battle.","success");if(e==="CoOp")return c.instance.prodigy.world.$(r.data.zone),l.fire("Escaped!","You have successfully escaped from the battle.","success");if(e==="SecureBattleRevamp"){let t=c.instance?._game?._state?._current?._battleController;return!t||typeof t.attemptEscape!="function"?l.fire("Error","BattleController not available on current state.","error"):(await t.attemptEscape(),l.fire("Escaped!","You have successfully escaped from the PvE battle.","success"))}return["Battle","SecureBattle"].includes(e)?(Object.fromEntries(c.instance.game.state.states)[e].runAwayCallback(),l.fire("Escaped!","You have successfully escaped from the PvE battle.","success")):l.fire("Invalid State.","You are currently not in a battle.","error")});new p(u.battle,"Win Battle [PvE]","Instantly win the current PvE battle.").setClick(async()=>{if(Ae.state.current!=="SecureBattleRevamp")return l.fire("Invalid State.","You are currently not in a PvE battle.","error");let e=c.instance?.game?._state?._current?._battleController;return!e||typeof e.onVictory!="function"?l.fire("Error","BattleController not available on current state.","error"):(await e.onVictory(),l.fire("Victory!","You won the battle!","success"))});function Ts(){let e=c?.prodigy??c?.instance?.prodigy;return e?._currentBattlePass??e?._battlePass??null}function bt(e){let t=Ts();if(!t||typeof t!="object")return g.fire("Error","Battle Pass not found.","error");let n=t._tiers;return!n||typeof n!="object"?g.fire("Error","Tiers not found in battle pass.","error"):(Object.values(n).forEach(o=>{o&&(o.isCompleted=!0,o[e]&&(o[e].claimed=!1,o[e].claimable=!0))}),l.fire("Success!","Rewards unlocked.","success"))}new p(u.battlepass,"Treasure Free","Unlocks all free Battle Pass tier rewards.").setClick(async()=>bt("freeReward"));new p(u.battlepass,"Treasure Core","Unlocks all Core (bottom premium) Battle Pass tier rewards.").setClick(async()=>bt("bottomPremiumReward"));new p(u.battlepass,"Treasure Plus","Unlocks all Plus (top premium) Battle Pass tier rewards.").setClick(async()=>bt("topPremiumReward"));var W=["Boots","Buddies","Fossils","Hats","Items","Key Items","Tower Town Frames","Tower Town Interiors","Mounts","Outfits","Relics","Weapons","Currencies"],C=["boots","follow","fossil","hat","item","key","mathTownFrame","mathTownInterior","mount","outfit","spellRelic","weapon","currency"],Y=(e,t)=>e.map(n=>({ID:n.ID,N:t})).filter(n=>n!==void 0),Mn=(e,t)=>e.map(n=>({ID:n.ID,quantity:t})).filter(n=>n!==void 0);function $n(e){if(c.player.userID!==e){let n=c.instance.prodigy.friendsListNetworkHandler.friendsList.length,o=c.instance.prodigy.friendsListNetworkHandler.classList.length;c.instance.prodigy.gameContainer.get("2e1-e659").create("house-visit","click","hub",n,o,null,null,e).broadcast()}let t=c.instance.prodigy.world.getZone(c.instance.prodigy.world.getCurrentZone());return t?t.handleLeaving(2,()=>Ds(e)):g.fire({title:"Error",text:"You are not in a zone!",icon:"error"})}function Ds(e){c.instance.prodigy.loading(!0);let t=n=>{let o=n!=null?n[e]:null;if(o!==null&&o.house!==void 0&&o.house!==null){c.instance.prodigy.loading(!1);let s=c.cloneDeep(c.player.house);return s.setItems(o.house),o.data.allowsHouseVisitors!==void 0&&o.data.allowsHouseVisitors!==null&&o.data.allowsHouseVisitors?c.instance.prodigy.world._("house",null,null,{house:s,getAllowsHouseVisitors:()=>o.data.allowsHouseVisitors!==void 0&&o.data.allowsHouseVisitors!==null?o.data.allowsHouseVisitors:!1,setAllowsHouseVisitors:a=>{o.data.allowsHouseVisitors=a}}):g.fire(`Teleporting to ${e} is not allowed.`,"Try another user.","error")}};return c.network.getCharData(e.toString(),["house","data"],t,t),l.fire("Teleported to house","You have been teleported to the house!","success")}var Ge=async e=>(await g.fire({input:"select",inputOptions:new Map(c.player.kennel.data.map((n,o)=>[o.toString(),`Level ${n.level} - ${n.nickname??c.gameData.pet.find(s=>+s.ID==+n.ID)?.data.name??"Unknown"}`])),title:"Choose Pet",text:e})).value,Ee=[125,126,127,128,129,134,135,136,137];function me(){c.gameData.pet.forEach(e=>{r.kennel.addPet(e.ID,P,26376,100)}),r.kennel._encounterInfo._data.pets=[],c.gameData.pet.map(e=>{r.kennel._encounterInfo._data.pets.push({firstSeenDate:Date.now(),ID:e.ID,timesBattled:1,timesRescued:1})}),r.kennel.petTeam.forEach(e=>{e&&e.assignRandomSpells&&e.assignRandomSpells()})}function fe(e){C.forEach(t=>{r.backpack.data[t]=Y(c.gameData[t].filter(n=>t==="follow"?!Ee.includes(n.ID):n),e)}),c.gameData.dorm.forEach(t=>r.house.data.items[t.ID]={A:[],N:e})}function we(){let e=()=>r.backpack.data.item.findIndex(t=>t.ID===84||t.ID===85||t.ID===86);for(;e()>-1;)r.backpack.data.item.splice(e(),1)}var On=!1;function vt(e){On=e}(async()=>setInterval(async()=>{On&&c.instance.prodigy.open.menuCloseAll()},200))();new p(u.beta,"Edit Pet [BETA]","Edit a pet.").setClick(async()=>{if(!(await E.fire({title:"Hang on!",html:"This hack may damage your account with various bugs, for example you may be unable to do Rune Run.

        Proceed?",icon:"warning"})).value)return console.log("Cancelled.");let e=await Ge("Choose the pet to edit.");if(e===void 0)return;let t=r.kennel.data[e],n=await g.fire({input:"select",inputOptions:{level:"Level",attacks:"Attacks",name:"Name"},title:"Edit Property",text:"What do you want to edit?"});if(n.value!==void 0){if(n.value==="level"){let o=await b.fire("Level Number","What level do you want to set your pet to?","question");return o.value===void 0?void 0:(t.level=+o.value,l.fire("Success!","The pet's level has been set.","success"))}else if(n.value==="attacks"){let o=c.gameData.spell,s=document.createElement("div"),a=document.createElement("select");a.classList.add("selectSpell");for(let m of o){let f=document.createElement("option");f.value=m.ID.toString(),f.innerText=`${m.ID}: ${m.name} (${m.data.element}) - Damage: ${m.data.damage}`,a.options.add(f)}s.append(a),s.append(a.cloneNode(!0));let d=await g.fire({title:"Attack List",focusConfirm:!1,showCancelButton:!0,html:s,preConfirm:()=>Array.prototype.slice.call(document.querySelectorAll(".selectSpell")).map(m=>m.options[m.selectedIndex].value)});return d.value===void 0?void 0:(t.foreignSpells.splice(0,2,...d.value.map(m=>+m)),l.fire("Attacks updated!","The attack list of the pet you selected has been edited.","success"))}else if(n.value==="name"){let o=await K.fire("Input Name","What do you want to name the pet?","question");return o.value===void 0?void 0:(t.nickname=o.value,l.fire("Successfully renamed!","The name of the pet has been changed.","success"))}}});new k(u.beta,"(client side) Toggle Invisibility [BETA]","Lets you appear invisible on your own screen.").setEnabled(async()=>{he.user.visible=!1}).setDisabled(async()=>{he.user.visible=!0});new k(u.beta,"Toggle Close Popups [BETA]","Automatically closes popups in Prodigy.").setEnabled(async()=>(vt(!0),l.fire("Enabled","Toggle Close Popups is now enabled.","success"))).setDisabled(async()=>(vt(!1),l.fire("Enabled","Toggle Close Popups is now disabled.","success")));new p(u.beta,"Hypermax Account [BETA]").setClick(async()=>{if(!(await E.fire({title:"Hang on!",html:"This hack will damage your account with various bugs, for example you may be unable to do Rune Run/Arena, amd you will recieve 418s and inavtivity kicks.

        Proceed?",icon:"warning"})).value)return;r.data.gold=99e5,console.log("Set player gold to 9900000.");let t=100-2,n=1.042;r.data.stars=Math.round((1-Math.pow(n,t))/(1-n)*20+10),r.data.level=100,r.getLevel=()=>r.data.level,console.log("Set player level to 100"),r.data.bountyScore=100,console.log("Set player's bounty points to 100.");for(let f=0;f<99;f++)V.giftBoxController.receiveGiftBox(null,Ie("giftBox",1));console.log("Obtained 100 conjure cubes."),r.data.win=P,console.log("Set player's wins to VERY_LARGE_NUMBER"),r.data.loss=0,console.log("Set player's losses to 0."),r.modifiers.damage=P,console.log("Enabled damage multiplier."),r.pvpHP=P,r.getMaxHearts=()=>P,console.log("PvP health obtained.");for(var o=0;o<100;o++)r.achievements.data.progress[o]=10;console.log("Obtained all achievements."),r.data.tower=100,console.log("Set tower floor to 100."),r.getMaxHearts=()=>P,r.pvpHP=P,r.data.hp=P,console.log("Maxed out PvE health."),fe(99e4),we(),l.fire("Success!","All items added!","success"),console.log("All items added!"),r.backpack.data.mount=Y(c.gameData.mount,1),console.log("Added all mounts."),me(),console.log("Added all pets."),c.gameData.pet.filter(f=>[158,166,168].includes(f.ID)).forEach(f=>{r.kennel.addPet(f.ID,P,26376,100)}),r.kennel.petTeam.forEach(f=>{f&&f.assignRandomSpells&&f.assignRandomSpells()}),console.log("Added Mythical Epics."),c.gameData.pet.filter(f=>[125,126,127,128,129,130,131,132,133].includes(f.ID)).forEach(f=>{r.kennel.addPet(f.ID,P,26376,100)}),r.kennel.petTeam.forEach(f=>{f&&f.assignRandomSpells&&f.assignRandomSpells()}),console.log("Added Legacy Epics."),c.constants.constants["GameConstants.Inactivity.LOG_OUT_TIMER_SECONDS"]=0,console.log("Inactivity Kick Disabled."),r._playerContainer.walkSpeed=20,console.log("Player walkspeed set to 20.");let d=100,m;return Array.from(c.instance.prodigy.gameContainer._inversifyContainer._bindingDictionary._map).forEach(f=>{try{c.instance.prodigy.gameContainer.get(f[0]).battleData&&(m=f[0])}catch{console.log(`Error for ${f[0]}`)}}),c.instance.prodigy.gameContainer.get(m).battleData._secureCharacterState._data.inventory.orb=Mn(c.gameData.orb,d),r.equipment.setHat(200),r.equipment.setBoots(93),r.equipment.setOutfit(161),r.equipment.setWeapon(196),$(),console.log("Character Saved."),r.appearanceChanged=!0,console.log("Appearance Refreshed."),c.instance.prodigy.open.menuCloseAll(),console.log("Popups closed."),$(),console.log("Character Saved."),console.log("Max Account Successful."),l.fire("Maxed!","Check your backpack!","success")});new p(u.inventory,"Item stacker").setClick(async()=>{let e=await b.fire("Amount","How many of every item would you like?","question");if(e.value&&(await E.fire("Are you sure you want to get all items in the game?")).value)return fe(e.value),we(),l.fire("Success!","All items added!","success")});new p(u.inventory,"Clear inventory").setClick(async()=>{(await E.fire("Are you sure you want to clear your inventory?")).value&&(Object.keys(r.backpack.data).forEach(e=>r.backpack.data[e]=[]),l.fire("Success!","Inventory cleared.","success"))});new p(u.inventory,"Selector (Basic)").setClick(async()=>{let e=await g.fire({title:"What would you like to obtain?",input:"select",inputOptions:W,inputPlaceholder:"Select...",inputValidator:t=>t?"":"Please select which you'd like to obtain.",showCancelButton:!0}).then(async t=>{let n=parseInt(t.value),o=W[n],s=C[n];if(!o)return;let a=await b.fire("Amount","How many each object would you like?","question");a.value&&(await E.fire(`Are you sure you want to get all ${o.toLowerCase()}?`)).value&&(r.backpack.data[s]=Y(c.gameData[s].filter(d=>s==="follow"?!Ee.includes(d.ID):d),a.value),l.fire(`${o} Added!`,`All ${o.toLowerCase()} have been added to your inventory!`,"success"),$())})});new p(u.inventory,"Selector (Advanced)","Choose a specific object and quantity to obtain.").setClick(async()=>{let e=await g.fire({title:"What would you like to obtain?",input:"select",inputOptions:W,inputPlaceholder:"Select...",inputValidator:t=>t?"":"Please select which you'd like to obtain.",showCancelButton:!0}).then(async t=>{if(!c.gameData[C[t.value]])return;let n=[];c.gameData[C[t.value]].forEach(s=>{n.push(s.data.name)});let o=await g.fire({title:`What specific object categorized as ${W[t.value].toLowerCase()} would you like to get?`,input:"select",inputOptions:n,inputPlaceholder:"Select...",inputValidator:s=>s?"":"Please select which you'd like to get.",showCancelButton:!0}).then(async s=>{let a=parseInt(s.value);if(!c.gameData[C[t.value]][a])return;let d=await b.fire("Amount","How many of the object would you like?","question");if(!d.value)return;let m=r.backpack.data[C[t.value]].findIndex(f=>f.ID===c.gameData[C[t.value]][a].ID);return m===-1?r.backpack.data[C[t.value]].push({ID:c.gameData[C[t.value]][a].ID,N:d.value}):r.backpack.data[C[t.value]][m].N=d.value,console.log(c.gameData[C[t.value]][a].ID),$(),l.fire(`${W[t.value]} Added!`,`Your selected ${W[t.value].toLowerCase()} have been added.`,"success")})})});new p(u.inventory,"Obtain All Furniture").setClick(async()=>{let e=await b.fire("Amount","How many of each piece of furniture would you like?","question");if(e.value&&(await E.fire("Are you sure you want to get all furniture?")).value)return c.gameData.dorm.forEach(t=>r.house.data.items[t.ID]={A:[],N:e.value}),l.fire("Furniture Added!","All furniture has been added to your inventory!","success")});new p(u.inventory,"Obtain All Mounts","This gives you all of the mounts in the game.").setClick(async()=>(r.backpack.data.mount=Y(c.gameData.mount,1),l.fire("Mounts Added!","All mounts have been added to your inventory!")));new p(u.inventory,"Remove item").setClick(async()=>{let e=await g.fire({title:"What category would you like to remove an item from?",input:"select",inputOptions:W,inputPlaceholder:"Select...",inputValidator:a=>a?"":"Please select which you'd like to obtain.",showCancelButton:!0});if(!c.gameData[C[e.value]])return;let t=c.gameData[C[e.value]].map(a=>a.data.name),n=await g.fire({title:`What specific object categorized as ${W[e.value].toLowerCase()} would you like to remove?`,input:"select",inputOptions:t,inputPlaceholder:"Select...",inputValidator:a=>a?"":"Please select which you'd like to get.",showCancelButton:!0});if(n=parseInt(n.value),!c.gameData[C[e.value]][n])return;let o=await b.fire("Amount","How many of the object would you like to remove?","question");if(!o.value)return;if(r.backpack.data[C[e.value]].findIndex(a=>a.ID===c.gameData[C[e.value]][n].ID)===-1){await g.fire("Item Does Not Exist",`You do not have any ${c.gameData[C[e.value]][n].name}.`,"error");return}let s=r.backpack.data[C[e.value]].findIndex(a=>a.ID===c.gameData[C[e.value]][n].ID);return r.backpack.data[C[e.value]][s].N-=parseInt(o.value),r.backpack.data[C[e.value]][s].N<=0&&r.backpack.data[C[e.value]].splice(s,1),$(),l.fire("Removed!",`Successfully removed ${o.value} ${c.gameData[C[e.value]][n].name}!`,"success")});new p(u.inventory,"Get All Gems","Adds one of each gem type to your backpack and saves.").setClick(async()=>([3,4,10,11,17].forEach(t=>{let n=r.backpack.data.key.find(o=>o.ID===t);n?n.N+=1:r.backpack.data.key.push({ID:t,N:1})}),r.appearance.updated=!0,r.updated=!0,r.saveEnabled=!0,typeof r.forceSaveCharacter=="function"&&r.forceSaveCharacter(),r.appearanceChanged=!0,r.backpack.updated=!0,l.fire("Done!","All gems added to your backpack.","success")));var Ke=!0;new k(u.location,"WASD Movement","Allows you to walk through walls or on air with WASD movement in Prodigy.").setEnabled(async()=>(Ke=!0,l.fire("Enabled!","WASD Movement is now enabled.","success"))).setDisabled(async()=>(Ke=!1,l.fire("Disabled!","WASD Movement is now disabled.","success"))).status=!0;new p(u.location,"Edit walkspeed","Lets you set your walkspeed.").setClick(async()=>{let e=await K.fire("What do you want to set your walk speed to?");if(e.value){if(r._playerContainer)r._playerContainer.walkSpeed=parseFloat(e.value)||1.5;else{let t=setInterval(()=>{r._playerContainer&&(clearInterval(t),r._playerContainer.walkSpeed=parseFloat(e.value))},100)}return l.fire("Success!",`Successfully made walk speed ${parseFloat(e.value)||1.5}!`,"success")}});var Hn=-1;new k(u.location,"Toggle Click Teleporting").setEnabled(async()=>(Hn=setInterval(()=>{try{r._playerContainer.walkSpeed=500}catch{}},16),l.fire("Success!","Successfully enabled teleport click.","success"))).setDisabled(async()=>(clearInterval(Hn),r._playerContainer.walkSpeed=1.5,l.fire("Success!","Successfully disabled teleport click.","success")));new p(u.location,"Teleport To Map (interactive)").setClick(async()=>{let e=g.mixin({focusConfirm:!1,showCancelButton:!0,preConfirm:()=>document.querySelector(".radioDiv[checked]")?.getAttribute("zone")}),t=document.createElement("div");t.classList.add("radioContainer");for(let m of Object.keys(V.world.zones)){let f=document.createElement("DIV");f.classList.add("radioDiv"),f.setAttribute("zone",m),f.innerText=m,f.onclick=()=>{document.querySelectorAll(".radioDiv[checked]").forEach(I=>I.removeAttribute("checked")),f.setAttribute("checked","")},t.append(f)}let n=await e.fire({title:"Teleport Zone",html:t,customClass:{popup:"radioSwal"}});if(!n.value)return;let o=Object.keys(V.world.zones[n.value].maps),s=await g.fire({input:"select",inputOptions:new Map(o.map(m=>[m,m])),title:"Map",text:"Which map in the zone do you want to teleport to?"});if(!s.value)return;let a=(await b.fire("Please enter the x to teleport to. (Try 500?)")).value||500,d=(await b.fire("Please enter the y to teleport to. (Try 500?)")).value||500;return V.world.zones[n.value].teleport(s.value,a,d,{},{}),l.fire("Teleported","You have been teleported!","success")});new p(u.location,"Teleport to house by userID").setClick(async()=>{let e=(await b.fire("Please enter the userID.")).value;if(e)return $n(e),l.fire("Teleported!","You have been teleported!","success")});new p(u.location,"Get Map Location").setClick(async()=>{let e=r.data.zone;navigator.clipboard.writeText(e).then(async function(){return console.log("Async: Copying to clipboard was successful!"),g.fire({title:"Map Location",html:`You are at
        ${e} .
        You can save this to get to the same zone.

        Your location is has also been copied to your clipboard.`,icon:"info"})},async function(t){return console.error("Async: Could not copy text: ",t),g.fire({title:"Map Location",html:`You are at
        ${e} .
        You can save this to get to the same zone.`,icon:"info"})})});new k(u.minigames,"69x Walk Speed [Dyno Dig]","Walk so fast that you're teleporting, in Dyno Dig.").setEnabled(async()=>(c.instance.game.state.states.get("DinoDig").walkSpeed=69,l.fire("Enabled!","You will now walk so fast that you're teleporting in Dyno Dig.","success"))).setDisabled(async()=>(c.instance.game.state.states.get("DinoDig").walkSpeed=1.5,l.fire("Disabled!","You will now walk at normal speed, in Dyno Dig.","success")));new p(u.minigames,"Dino Dig +100 Days","Adds 100 days to the active Dino Dig timer.").setClick(async()=>{let e=c.instance.game.state.states.get("DinoDig");return e?.timer?.addTime?(e.timer.addTime(864e7),l.fire("Done!","Added 100 days to the Dino Dig timer.","success")):g.fire("Error","You are not currently in Dino Dig.","error")});new p(u.minigames,"End Dino Dig","Instantly ends the current Dino Dig session.").setClick(async()=>{let e=c.instance.game.state.states.get("DinoDig");return e?.timer?.addTime?(e.timer.addTime(-9e15),l.fire("Done!","Dino Dig session ended.","success")):g.fire("Error","You are not currently in Dino Dig.","error")});var kt=document.createElement("button"),Se=null;function _n(){Se||Bs()}function Nn(){Se&&(clearInterval(Se),Se=null),document.getElementById("fps-counter")?.remove()}function Bs(){kt.id="fps-counter",We?.prepend(kt),Se=setInterval(()=>{kt.innerText=r.game.fps._framerate.toFixed(2)+" FPS"},300)}new p(u.misc,"Skip Tutorial").setClick(async()=>{let e=(t,n,o,s)=>{c.instance.prodigy.world.getZone(t).testQuest(n,o,s);try{Object.fromEntries(c.instance.game.state.states).TileScreen.process()}catch{}};e("house",2),e("academy",2),r.state.set("tutorial-0",4),r.backpack.addKeyItem(13,0),r.tutorial.data.menus[14]=[1],c.instance.prodigy.open.map(!0,[]),r.onTutorialComplete(),r.data.level=Math.max(r.data.level,5)});new k(u.beta,"FPS Counter [BETA]","Shows you a framerate counter").setEnabled(async()=>{_n()}).setDisabled(async()=>{Nn()});try{let e=null;new k(u.misc,"Unlimited Spins","Lets you spin the wheel as many times as you want!").setEnabled(async()=>(e=r.canSpin,r.canSpin=()=>!0,l.fire("Enabled!","You can now spin the wheel as many times as you want!","success"))).setDisabled(async()=>(r.canSpin=e,l.fire("Disabled!","You can now spin the wheel only when allowed.","success")))}catch(e){console.error("Unlimited Spins ERROR: "+e)}new p(u.misc,"Reset Account","Completely resets your account.").setClick(async()=>{if((await E.fire("Are you sure you want to reset your account?","This action is not reversible.")).value)return r.resetAccount(),g.fire("Reset!","Your account has been reset. Reload Prodigy for the full effect.","success")});new p(u.misc,"[Fix] Fix Battle Crash").setClick(async()=>(r.kennel.petTeam.forEach(e=>{e&&e.assignRandomSpells&&e.assignRandomSpells()}),l.fire("Success!","Fixed kennel attack bug!","success")));new p(u.misc,"[Fix] Stuck in Unfinished Tower Fix","Takes you out of an unfinished tower if you're stuck in one.").setClick(async()=>(c.instance.prodigy.world.zones.house.teleport("exit"),l.fire("Success!","You've been teleported outside of your house.","success")));new k(u.misc,"Disable Monster Encounters").setEnabled(async()=>F("GameConstants.Debug.SCALE_ENCOUNTER_DISTANCE",0)?l.fire("Enabled!","Monsters will no longer battle you.","success"):l.fire("Error","FlagProvider service not found.","error")).setDisabled(()=>(F("GameConstants.Debug.SCALE_ENCOUNTER_DISTANCE",1),l.fire("Disabled!","Monsters will now battle you.","success")));new p(u.misc,"Bobbified","Turns you into Bobby Fancywoman (level 69, specific appearance).").setClick(async()=>{if((await E.fire("Are you sure?","You will be transformed into Bobby Fancywoman.")).value)return r.name.data.firstName=44,r.name.data.middleName=754,r.name.data.lastName=882,r.data.stars=-1e22,r.data.level=69,r.appearance.setEyeColor(1),r.appearance.setFace(4),r.appearance.setHair(19,1),r.appearance.setSkinColor(1),r.equipment.setFollow(19),r.equipment.setHat(19),r.equipment.setBoots(19),r.equipment.setOutfit(19),r.equipment.setWeapon(19),l.fire("Done!","You are now Bobby Fancywoman.","success")});new p(u.pets,"Get All Pets").setClick(async()=>(await E.fire("Would you like to add all pets to your pets?")).value?(me(),l.fire("Success!","All pets have been added!","success")):console.log("Cancelled"));new p(u.pets,"Get All Legacy Epics").setClick(async()=>(await E.fire({title:"This may damage your account.",html:"Attempting to add legacy epics may damage your account.

        Warning: this does NOT save on reload — the pets will disappear after refreshing.

        Would you still like to add all legacy epics to your team?",icon:"warning"})).value?(c.gameData.pet.filter(t=>[125,126,127,128,129,130,131,132,133].includes(t.ID)).forEach(t=>{r.kennel.addPet(t.ID,P,26376,100)}),r.kennel.petTeam.forEach(t=>{t&&t.assignRandomSpells&&t.assignRandomSpells()}),l.fire("Success!","All legacy epics have been added!","success")):console.log("Cancelled"));new p(u.pets,"Get All Mythical Epics").setClick(async()=>(await E.fire({title:"Add all mythical epics?",html:"Warning: this does NOT save on reload — the pets will disappear after refreshing.

        Would you like to add all mythical epics to your pets?",icon:"warning"})).value?(c.gameData.pet.filter(t=>[158,164,165,166,167,168,169,170,171,189].includes(t.ID)).forEach(t=>{r.kennel.addPet(t.ID,P,26376,100)}),r.kennel.petTeam.forEach(t=>{t&&t.assignRandomSpells&&t.assignRandomSpells()}),l.fire("Success!","All mythical epics have been added!","success")):console.log("Cancelled"));new p(u.pets,"Clear Pets").setClick(async()=>(await E.fire("Would you like to delete all of your pets?")).value?(r.kennel.data.length=0,l.fire("Success!","Your pets have been cleared!","success")):console.log("Cancelled"));new p(u.pets,"Add Pet","Adds a pet from a list.").setClick(async()=>{let e=await g.fire({input:"select",inputOptions:new Map(c.gameData.pet.map(t=>[t.ID.toString(),`${t.ID}: ${t.data.name}`])),title:"Choose Pet",text:"Which pet do you want to obtain?"});if(e.value!==void 0)return r.kennel.addPet(e.value),r.kennel._encounterInfo._data.pets.push({firstSeenDate:Date.now(),ID:e.value,timesBattled:1,timesRescued:1}),l.fire("Success!","Your chosen pet has been added to your pets!","success")});new p(u.pets,"Uncap pet level [Client Side]","Change your pet's level to anything, even over 100. This hack won't save when you reload Prodigy.").setClick(async()=>{let e=r.kennel.petTeam.slice(0);e.shift();let t=e.map(a=>a.getName()),n=await g.fire({title:"Which pet would you like to edit?",input:"select",inputOptions:t,inputPlaceholder:"Select...",inputValidator:a=>a?"":"Please select which you'd like to obtain.",showCancelButton:!0}),o=await b.fire("Level","What would you like to set your pet's level to? (Can be set over 100)","question");if(!o.value)return;let s=o.value;return r.kennel.petTeam[parseInt(n.value)+1].getLevel=()=>Number(s),l.fire("Updated!","The level of your pet was successfully updated. Note: this hack is client-side.","success")});new p(u.pets,"Delete Pet","Delete a pet.").setClick(async()=>{let e=await Ge("Which pet do you wish to delete?");if(e!==void 0)return r.kennel.data.splice(e,1),l.fire("Successfully deleted!","The selected pet was deleted successfully.","success")});new p(u.pets,"All Pets Level 150","Replaces all pets with every pet at level 150. WARNING: Erases current pet data.").setClick(async()=>{if((await E.fire("Are you sure?","This will erase all your current pet data and replace it with every pet at level 150.")).value)try{let e=(d,m)=>Math.floor(Math.random()*(m-d+1)+d),t=(d,m)=>{let f=m.data.statHealth,I=500/1.25*Math.pow(Math.pow(1.25,.25),f-1),ge=100/1.25*Math.pow(Math.pow(1.25,.25),f-1);return Math.ceil(I+(d-1)*ge)},s=(d=>{if(d===1)return 0;if(d===2)return 10;let m=d-2,f=1.042;return Math.round((1-Math.pow(f,m))/(1-f)*20+10)})(150),a=c.gameData.pet;return r.kennel.data.length=0,a.forEach(d=>{r.kennel.addPet(d.ID,t(150,d),s,150)}),r.kennel._encounterInfo._data.pets=a.map(d=>({firstSeenDate:Date.now()-e(2e4,12e4),ID:d.ID,timesBattled:1,timesRescued:1,rescueAttempts:1})),r.kennel.petTeam.forEach(d=>{d&&d.assignRandomSpells&&d.assignRandomSpells()}),g.fire("Done!","All pets added at level 150. Leave the game open for ~2 minutes to fully sync.","success")}catch(e){return g.fire("Error","Failed to add pets: "+e,"error")}});new p(u.player,"Max Account").setClick(async()=>{if(!(await E.fire("Are you sure that you want to max your account?","We recommend doing this on an alt.")).value)return console.log("Cancelled");r.data.gold=99e5,console.log("Set player gold to 9900000.");let t=100-2,n=1.042;r.data.stars=Math.round((1-Math.pow(n,t))/(1-n)*20+10),r.data.level=100,r.getLevel=()=>r.data.level,console.log("Set player level to 100"),r.data.bountyScore=100,console.log("Set player's bounty points to 100.");for(let d=0;d<99;d++)V.giftBoxController.receiveGiftBox(null,Ie("giftBox",1));console.log("Obtained 100 conjure cubes.");for(var o=0;o<100;o++)r.achievements.data.progress[o]=10;console.log("Obtained all achievements."),r.data.tower=100,console.log("Set tower floor to 100."),fe(1),we(),l.fire("Success!","All items added!","success"),console.log("All items added!"),r.backpack.data.mount=Y(c.gameData.mount,1),console.log("Added all mounts.");let s="currency",a=6969420;return r.backpack.data[s]=Y(c.gameData[s].filter(d=>s==="follow"?!Ee.includes(d.ID):d),a),me(),console.log("Added all pets."),r.equipment.setHat(200),r.equipment.setBoots(93),r.equipment.setOutfit(161),r.equipment.setWeapon(196),r.appearanceChanged=!0,console.log("Appearance Refreshed."),$(),console.log("Character Saved."),console.log("Max Account Successful."),l.fire("Maxed!","Check your backpack!","success")});new p(u.player,"Set Gold").setClick(async()=>{let e=await b.fire("Gold Amount","What number do you want to set your gold to?","question");if(e.value!==void 0)return e.value>1e7?l.fire("Error","Cannot have more than 10,000,000 gold.","error"):(r.data.gold=+e.value,l.fire("Success!",`You now have ${e.value} gold.`,"success"))});new p(u.player,"Set Magicoin","Set your Magicoin amount.").setClick(async()=>{let e=await b.fire("Magicoin Amount","What number do you want to set your Magicoin to?","question");if(e.value!==void 0)try{return r._secureInventory._cacheByPath.currency[27].stackable.quantity=+e.value,l.fire("Done!",`Magicoin set to ${e.value}.`,"success")}catch{return g.fire("Error","Failed to set Magicoin. The path may have changed.","error")}});new p(u.player,"Set Level").setClick(async()=>{let e=await b.fire("Level","What number do you want to set your level to?","question");if(e.value===void 0)return;if(e.value===1)return 0;let t=e.value-2,n=1.042;return r.data.stars=Math.round((1-Math.pow(n,t))/(1-n)*20+10),r.data.level=+e.value,r.getLevel=()=>r.data.level,l.fire("Success!",`You are now level ${e.value}.`,"success")});new p(u.player,"Get member stars").setClick(async()=>{let e=await b.fire("Stars","How many member stars do you want?","question");if(e.value!==void 0)return r.data.storedMemberStars=e.value,l.fire("Success!",`You have set your member stars to ${e.value}.`,"success")});new p(u.player,"Set Bounty Points").setClick(async()=>{let e=await b.fire("Bounty Points","What number do you want to set your bounty points to? (Max is 100)","question");if(e.value!==void 0)return r.data.bountyScore=Math.min(+e.value,100),l.fire("Success!",`You now have ${r.data.bountyScore} bounty point${r.data.bountyScore!=1?"s":""}.`,"success")});new p(u.player,"Set Wins").setClick(async()=>{let e=await b.fire("Wins","What number do you want to set your wins to?","question");if(e.value!==void 0)return r.data.win=+e.value,l.fire("Success!",`You have set your win${e.value!=1?"s":""} to ${e.value}.`,"success")});new p(u.player,"Set Losses").setClick(async()=>{let e=await b.fire("Losses","What number do you want to set your losses to?","question");if(e.value!==void 0)return r.data.loss=+e.value,l.fire("Success!",`You have set your loss${e.value!=1?"es":""} to ${e.value}.`,"success")});var Pe=null;new k(u.player,"Toggle Membership (Client Side)").setEnabled(async()=>c.functions?.setMembership?.(!0)?(Pe||(Pe=r.getMemberTier?.bind(r)),r.getMemberTier=()=>103,r.appearanceChanged=!0,l.fire({icon:"success",title:"Membership enabled (cosmetic)",html:"Use Selector (Advanced) to get member-only items."})):l.fire("Error","Membership service not found.","error")).setDisabled(()=>c.functions?.setMembership?.(!1)?(Pe&&(r.getMemberTier=Pe,Pe=null),r.appearanceChanged=!0,l.fire("Success!","You no longer have Prodigy membership!","success")):l.fire("Error","Membership service not found.","error"));new p(u.player,"Set name (Client side only)").setClick(async()=>{let e=await K.fire("What would you like to set your name to?");if(e.value)return r.getName=()=>e.value,r.appearanceChanged=!0,l.fire("Changed!","Your name was changed.")});new p(u.player,"Change Name","Change the name of your wizard.").setClick(async()=>{let e=c.gameData.name,t=document.createElement("div"),n=(a,d)=>{let m=document.createElement("select");m.classList.add("selectName");for(let f of a.entries()){let I=document.createElement("option");[I.value,I.innerText]=f,d(I.value)&&(I.selected=!0),m.options.add(I)}return m},o=(a,d)=>n(new Map(e.filter(m=>m.data.type===a).map(m=>[m.ID.toString(),m.name])),m=>d(+m));t.append(o(0,a=>a===r.name.data.firstName)),t.append(o(1,a=>a===r.name.data.middleName)),t.append(o(2,a=>a===r.name.data.lastName)),t.append(n(new Map([["null","[none]"]].concat(c.gameData.nickname.map(a=>[a.ID.toString(),a.name]))),a=>+a===r.name.data.nickname||String(r.name.data.nickname)===a));let s=await g.fire({title:"Set Player Name",focusConfirm:!1,showCancelButton:!0,html:t,preConfirm:()=>Array.prototype.slice.call(document.querySelectorAll(".selectName")).map(a=>a.options[a.selectedIndex].value)});if(s.value!==void 0)return s.value[3]==="null"&&(s.value[3]=null),[r.name.data.firstName,r.name.data.middleName,r.name.data.lastName,r.name.data.nickname]=s.value.map(a=>a&&+a),r.appearanceChanged=!0,l.fire("Name Changed!","Your name was successfully changed.","success")});new p(u.player,"Uncap player level (client side only)").setClick(async()=>{let e=await b.fire("Level","What would you like to set your level to? (Can be >100)","question");if(e.value)return localStorage.setItem("level",e.value),r.getLevel=()=>Number(e.value),l.fire("Updated!","Your level has been successfully updated","success")});new p(u.player,"Get all achievements").setClick(async()=>{for(var e=0;e<100;e++)r.achievements.data.progress[e]=10;return l.fire("Success!","Obtained all achievements!","success")});new p(u.player,"Fix Morph Crash").setClick(async()=>(r.getPlayerData().playerTransformation=void 0,r.appearanceChanged=!0,l.fire("Success!","Fixed morph crash bug.","success")));new p(u.player,"Permanent Morph","Makes Your Current Morph Last Forever.").setClick(async()=>r.data.playerTransformation?(r.data.playerTransformation.maxTime=1/0,r.data.playerTransformation.timeRemaining=1/0,l.fire("Success!","You're morph will last forever!","success")):g.fire("No Morph Active","Please use a Morph Marble and try again.","error"));new p(u.player,"Morph Player [BETA]","Morph into a pet, furnishing, or follow.").setClick(async()=>{if(!(await E.fire("This hack is in BETA","Expect bugs, and it might not work properly.")).value)return console.log("Cancelled");let e=await g.fire({title:"Which morph type?",input:"select",inputOptions:{pet:"Pet",dorm:"Furniture",follow:"Follow"},inputPlaceholder:"Morph Type",inputValidator:o=>o?"":"Please select a morph type.",showCancelButton:!0});if(!e?.value)return;let t={};c.gameData[e.value].forEach(o=>t[o.ID]=`${o.name} (${o.ID})`);let n=await g.fire({title:"Which morph?",input:"select",inputOptions:t,inputPlaceholder:"Morph ID",inputValidator:o=>o?"":"Please select a morph ID.",showCancelButton:!0});if(n.value)return r.getPlayerData().playerTransformation={transformType:e.value,transformID:n.value,maxTime:3600*1e3,timeRemaining:3600*1e3},r.appearanceChanged=!0,l.fire("Morphed!","You've been morphed.","success")});new p(u.player,"Complete Current Task In Quest","Completes current task in quest. (Use this button a lot to complete a quest.)").setClick(async()=>{let e={};Object.keys(c.instance.prodigy.world.zones).forEach(o=>{e[o]=c.instance.prodigy.world.zones[o].name});let t=(await K.fire({title:"What Quest Do You Want To Complete?",input:"select",inputOptions:e})).value;if(!t)return;let n=c.instance.prodigy.world.zones[t].getCurrentQuestID();return c.instance.prodigy.world.zones[t].completeQuest(n)?(c.instance.prodigy.world.goToZoneHub(t),l.fire("Success!",`Completed current task in the ${c.instance.prodigy.world.zones[t].name} quest successfully!`,"success")):l.fire("Could Not Complete Current Task In Quest.","There was an error completing the quest. Did you already complete it?","error")});new p(u.player,"Set Dark Tower Floor").setClick(async()=>{let e=await b.fire({title:"What floor do you want to be on, in the dark tower.",icon:"question",inputValidator:t=>t>100||t<1?`You can only be on floors from 1-100 not ${t}`:!1});if(e.value)return r.data.tower=parseInt(e.value),l.fire("Success!",`Successfully set dark tower floor to ${e}!`,"success")});new p(u.player,"Get UserID").setClick(async()=>{let e=r.userID;navigator.clipboard.writeText(e.toString()).then(function(){return console.log("Async: Copying to clipboard was successful!"),g.fire({title:"User ID",html:`Here is your User ID:
        ${e}
        You can use this for copying your account.

        Your UserID is has also been copied to your clipboard.`,icon:"info"})},function(t){return console.error("Async: Could not copy text: ",t),g.fire({title:"User ID",html:`Here is your User ID:
        ${e}
        You can use this for copying your account.`,icon:"info"})})});new p(u.player,"Copy Account","Copy Account From userID").setClick(async()=>{let e=(await b.fire("What is the userID of the account you want to copy?",void 0,"question")).value;if(!e)return;let t=await fetch(`https://api.prodigygame.com/game-api/v2/characters/${e}?fields=inventory%2Cdata%2CisMember%2Ctutorial%2Cpets%2Cencounters%2Cquests%2Cappearance%2Cequipment%2Chouse%2Cachievements%2Cstate&userID=${e}`,{headers:{Authorization:localStorage.JWT_TOKEN}});if(!t.ok)return l.fire("Error",`Failed to fetch account data: ${t.status} ${t.statusText}`,"error");let n=await t.json();if(!n[e])return l.fire("Error",`Account #${e} not found or data is invalid.`,"error");if((await E.fire("WARNING: This operation is IRREVERSIBLE!",`You are about to overwrite ALL of your character data with account #${e}. +`;Ve.style.color="white";de.append(Ve);var u={player:z("Player Mods"),inventory:z("Inventory Mods"),location:z("Location Mods"),pets:z("Pet Mods"),battle:z("Battle Mods"),battlepass:z("Battle Pass Mods"),minigames:z("Minigame Mods"),misc:z("Miscellaneous Mods"),utility:z("Utility Mods"),beta:z("Beta Testing | Beta Mods may damage your account")};localStorage.hasTip?console.log("Player already has tip."):((async()=>await J.fire({title:"Welcome!",html:"To get started with the hacks, click this dropdown!",icon:"info"}))(),localStorage.hasTip=!0,console.log("Player was shown the tip."));localStorage.getItem("level")&&(c.player.getLevel=()=>localStorage.getItem("level"),console.log("Loaded menu from localStorage."));window.__ORIGIN_ABORT__?.abort();var Bn=new AbortController;window.__ORIGIN_ABORT__=Bn;var ht=!0;document.addEventListener("keydown",function(e){e.key=="Shift"&&(e.stopImmediatePropagation(),console.log("Shift key was pressed."),ht==!0?(console.log("Hiding mod menu..."),document.getElementById("origin-menu").style.display="none",document.getElementById("origin-toggler").style.display="none",ht=!1,console.log("Hidden mod menu.")):(console.log("Showing mod menu..."),document.getElementById("origin-menu").style.display="block",document.getElementById("origin-toggler").style.display="block",ht=!0,console.log("Shown mod menu.")))},{capture:!0,signal:Bn.signal});var m=class{constructor(t,n,o){this.parent=t;this.name="",this.description="",this.element=document.createElement("button"),this.element.classList.add("menu-hack"),this.parent.append(this.element),n&&this.setName(n),o&&this.setDesc(o)}parent;element;name;description;setName(t){return this.element.innerText=t,this.name=t,this}setClick(t){return this.element.onclick=async()=>{await t(),M(),console.log(`Triggered ${this.name}.`)},this}setDesc(t){return this.element.title=t,this.description=t,this}};var k=class extends m{constructor(n,o,s){super(n,o,s);this.parent=n;this.element.setAttribute("status","false"),this.migrateOldKey(),this.setClick(async()=>{this.status=!this.status,this.status?(localStorage.setItem(this.getStorageKey(),"true"),await this.enabled?.()):(localStorage.setItem(this.getStorageKey(),"false"),await this.disabled?.())})}parent;enabled;disabled;migrateOldKey(){let n=this.getStorageKey();this.name!==n&&localStorage.getItem(this.name)!==null&&(localStorage.setItem(n,localStorage.getItem(this.name)),localStorage.removeItem(this.name))}getStorageKey(){let n=this.parent.querySelector("h1")?.innerText??"";return n?`${n}::${this.name}`:this.name}get status(){return JSON.parse(this.element.getAttribute("status"))}set status(n){this.element.setAttribute("status",n.toString())}setEnabled(n){if(this.enabled=n,localStorage.getItem(this.getStorageKey())==="true")try{this.element.click()}catch(o){console.warn(`[Origin] Failed to restore toggle state for "${this.name}":`,o)}return this}setDisabled(n){return this.disabled=n,this}};var g=J,G=g.mixin({input:"text",showCancelButton:!0,showConfirmButton:!0,toast:!1}),b=G.mixin({toast:!1,input:"number"}),l=g.mixin({toast:!0,position:"bottom"}),E=g.mixin({icon:"warning",showCancelButton:!0,toast:!1,confirmButtonText:"Confirm",cancelButtonText:"Cancel"}),Fs=g.mixin({icon:"info",showCancelButton:!1,toast:!1});window.Swal=g;function q(e,t){let n=c.constants;return!n||typeof n.set!="function"?!1:(n.set(e,t),!0)}new k(u.battle,"Instant Kill [PvE]","Makes your spells do insane damage in PvE!").setEnabled(async()=>(r.modifiers.damage=P,l.fire("Enabled!","You will now do insane damage in PvE!","success"))).setDisabled(()=>(r.modifiers.damage=1,l.fire("Disabled!","You will no longer do insane damage in PvE!","success")));new m(u.battle,"PvP Health [PvP]","Increases your HP in PvP by a hell ton.").setClick(async()=>(r.pvpHP=P,r.getMaxHearts=()=>P,l.fire("Success!","You now have lots of health!","success")));new m(u.battle,"Set Battle Hearts [PvP, PvE]","Sets your hearts in battle, automatically raise your max hearts in PvP or PvE.").setClick(async()=>{let e=await b.fire("Health Amount","How much HP do you want?","question");if(e.value!==void 0)return r.getMaxHearts=()=>+e.value,r.pvpHP=+e.value,r.data.hp=+e.value,l.fire("Success!","Your hearts have been set.","success")});new m(u.battle,"Fill Battle Energy [PvP, PvE]","Fills up your battle energy, if you are in PvP or PvE.").setClick(async()=>{let e=Pe.state.getCurrentState();return"teams"in e?(e.teams[0].setEnergy(99),l.fire("Success!","Your battle energy has been filled.","success")):l.fire("Error","You are currently not in a battle.","error")});new k(u.battle,"Disable math [PvP, PvE]","Disable math in PvP, PvE, anywhere! This doesn't work in the Floatling town.").setEnabled(async()=>q("GameConstants.Debug.EDUCATION_ENABLED",!1)?l.fire("Enabled!","You will no longer do Math!","success"):l.fire("Error","FlagProvider service not found.","error")).setDisabled(async()=>(q("GameConstants.Debug.EDUCATION_ENABLED",!0),l.fire("Disabled!","You will now do Math!","success")));new k(u.battle,"Skip enemy turn").setEnabled(async()=>q("GameConstants.Battle.SKIP_ENEMY_TURN",!0)?l.fire("Skipping!","Enemy turns will now be skipped.","success"):l.fire("Error","FlagProvider service not found.","error")).setDisabled(async()=>(q("GameConstants.Battle.SKIP_ENEMY_TURN",!1),l.fire("Disabled","Enemy turns will no longer be skipped.","success")));new m(u.battle,"Escape Battle [PvP, PvE]","Escape any battle, PvP or PvE!").setClick(async()=>{let e=Pe.state.current;if(e==="PVP")return Object.fromEntries(c.instance.game.state.states).PVP.endPVP(),l.fire("Escaped!","You have successfully escaped from the PvP battle.","success");if(e==="CoOp")return c.instance.prodigy.world.$(r.data.zone),l.fire("Escaped!","You have successfully escaped from the battle.","success");if(e==="SecureBattleRevamp"){let t=c.instance?._game?._state?._current?._battleController;return!t||typeof t.attemptEscape!="function"?l.fire("Error","BattleController not available on current state.","error"):(await t.attemptEscape(),l.fire("Escaped!","You have successfully escaped from the PvE battle.","success"))}return["Battle","SecureBattle"].includes(e)?(Object.fromEntries(c.instance.game.state.states)[e].runAwayCallback(),l.fire("Escaped!","You have successfully escaped from the PvE battle.","success")):l.fire("Invalid State.","You are currently not in a battle.","error")});new m(u.battle,"Win Battle [PvE]","Instantly win the current PvE battle.").setClick(async()=>{if(Pe.state.current!=="SecureBattleRevamp")return l.fire("Invalid State.","You are currently not in a PvE battle.","error");let e=c.instance?.game?._state?._current?._battleController;return!e||typeof e.onVictory!="function"?l.fire("Error","BattleController not available on current state.","error"):(await e.onVictory(),l.fire("Victory!","You won the battle!","success"))});function As(){let e=c?.prodigy??c?.instance?.prodigy;return e?._currentBattlePass??e?._battlePass??null}function yt(e){let t=As();if(!t||typeof t!="object")return g.fire("Error","Battle Pass not found.","error");let n=t._tiers;return!n||typeof n!="object"?g.fire("Error","Tiers not found in battle pass.","error"):(Object.values(n).forEach(o=>{o&&(o.isCompleted=!0,o[e]&&(o[e].claimed=!1,o[e].claimable=!0))}),l.fire("Success!","Rewards unlocked.","success"))}new m(u.battlepass,"Treasure Free","Unlocks all free Battle Pass tier rewards.").setClick(async()=>yt("freeReward"));new m(u.battlepass,"Treasure Core","Unlocks all Core (bottom premium) Battle Pass tier rewards.").setClick(async()=>yt("bottomPremiumReward"));new m(u.battlepass,"Treasure Plus","Unlocks all Plus (top premium) Battle Pass tier rewards.").setClick(async()=>yt("topPremiumReward"));var j=["Boots","Buddies","Fossils","Hats","Items","Key Items","Tower Town Frames","Tower Town Interiors","Mounts","Outfits","Relics","Weapons","Currencies"],C=["boots","follow","fossil","hat","item","key","mathTownFrame","mathTownInterior","mount","outfit","spellRelic","weapon","currency"],W=(e,t)=>e.map(n=>({ID:n.ID,N:t})).filter(n=>n!==void 0),Ln=(e,t)=>e.map(n=>({ID:n.ID,quantity:t})).filter(n=>n!==void 0);function Mn(e){if(c.player.userID!==e){let n=c.instance.prodigy.friendsListNetworkHandler.friendsList.length,o=c.instance.prodigy.friendsListNetworkHandler.classList.length;c.instance.prodigy.gameContainer.get("2e1-e659").create("house-visit","click","hub",n,o,null,null,e).broadcast()}let t=c.instance.prodigy.world.getZone(c.instance.prodigy.world.getCurrentZone());return t?t.handleLeaving(2,()=>Is(e)):g.fire({title:"Error",text:"You are not in a zone!",icon:"error"})}function Is(e){c.instance.prodigy.loading(!0);let t=n=>{let o=n!=null?n[e]:null;if(o!==null&&o.house!==void 0&&o.house!==null){c.instance.prodigy.loading(!1);let s=c.cloneDeep(c.player.house);return s.setItems(o.house),o.data.allowsHouseVisitors!==void 0&&o.data.allowsHouseVisitors!==null&&o.data.allowsHouseVisitors?c.instance.prodigy.world._("house",null,null,{house:s,getAllowsHouseVisitors:()=>o.data.allowsHouseVisitors!==void 0&&o.data.allowsHouseVisitors!==null?o.data.allowsHouseVisitors:!1,setAllowsHouseVisitors:a=>{o.data.allowsHouseVisitors=a}}):g.fire(`Teleporting to ${e} is not allowed.`,"Try another user.","error")}};return c.network.getCharData(e.toString(),["house","data"],t,t),l.fire("Teleported to house","You have been teleported to the house!","success")}var Ue=async e=>(await g.fire({input:"select",inputOptions:new Map(c.player.kennel.data.map((n,o)=>[o.toString(),`Level ${n.level} - ${n.nickname??c.gameData.pet.find(s=>+s.ID==+n.ID)?.data.name??"Unknown"}`])),title:"Choose Pet",text:e})).value,xe=[125,126,127,128,129,134,135,136,137];function me(){c.gameData.pet.forEach(e=>{r.kennel.addPet(e.ID,P,26376,100)}),r.kennel._encounterInfo._data.pets=[],c.gameData.pet.map(e=>{r.kennel._encounterInfo._data.pets.push({firstSeenDate:Date.now(),ID:e.ID,timesBattled:1,timesRescued:1})}),r.kennel.petTeam.forEach(e=>{e&&e.assignRandomSpells&&e.assignRandomSpells()})}function pe(e){C.forEach(t=>{r.backpack.data[t]=W(c.gameData[t].filter(n=>t==="follow"?!xe.includes(n.ID):n),e)}),c.gameData.dorm.forEach(t=>r.house.data.items[t.ID]={A:[],N:e})}function fe(){let e=()=>r.backpack.data.item.findIndex(t=>t.ID===84||t.ID===85||t.ID===86);for(;e()>-1;)r.backpack.data.item.splice(e(),1)}var $n=!1;function bt(e){$n=e}(async()=>setInterval(async()=>{$n&&c.instance.prodigy.open.menuCloseAll()},200))();new m(u.beta,"Edit Pet [BETA]","Edit a pet.").setClick(async()=>{if(!(await E.fire({title:"Hang on!",html:"This hack may damage your account with various bugs, for example you may be unable to do Rune Run.

        Proceed?",icon:"warning"})).value)return console.log("Cancelled.");let e=await Ue("Choose the pet to edit.");if(e===void 0)return;let t=r.kennel.data[e],n=await g.fire({input:"select",inputOptions:{level:"Level",attacks:"Attacks",name:"Name"},title:"Edit Property",text:"What do you want to edit?"});if(n.value!==void 0){if(n.value==="level"){let o=await b.fire("Level Number","What level do you want to set your pet to?","question");return o.value===void 0?void 0:(t.level=+o.value,l.fire("Success!","The pet's level has been set.","success"))}else if(n.value==="attacks"){let o=c.gameData.spell,s=document.createElement("div"),a=document.createElement("select");a.classList.add("selectSpell");for(let p of o){let f=document.createElement("option");f.value=p.ID.toString(),f.innerText=`${p.ID}: ${p.name} (${p.data.element}) - Damage: ${p.data.damage}`,a.options.add(f)}s.append(a),s.append(a.cloneNode(!0));let d=await g.fire({title:"Attack List",focusConfirm:!1,showCancelButton:!0,html:s,preConfirm:()=>Array.prototype.slice.call(document.querySelectorAll(".selectSpell")).map(p=>p.options[p.selectedIndex].value)});return d.value===void 0?void 0:(t.foreignSpells.splice(0,2,...d.value.map(p=>+p)),l.fire("Attacks updated!","The attack list of the pet you selected has been edited.","success"))}else if(n.value==="name"){let o=await G.fire("Input Name","What do you want to name the pet?","question");return o.value===void 0?void 0:(t.nickname=o.value,l.fire("Successfully renamed!","The name of the pet has been changed.","success"))}}});new k(u.beta,"(client side) Toggle Invisibility [BETA]","Lets you appear invisible on your own screen.").setEnabled(async()=>{ge.user.visible=!1}).setDisabled(async()=>{ge.user.visible=!0});new k(u.beta,"Toggle Close Popups [BETA]","Automatically closes popups in Prodigy.").setEnabled(async()=>(bt(!0),l.fire("Enabled","Toggle Close Popups is now enabled.","success"))).setDisabled(async()=>(bt(!1),l.fire("Enabled","Toggle Close Popups is now disabled.","success")));new m(u.beta,"Hypermax Account [BETA]").setClick(async()=>{if(!(await E.fire({title:"Hang on!",html:"This hack will damage your account with various bugs, for example you may be unable to do Rune Run/Arena, amd you will recieve 418s and inavtivity kicks.

        Proceed?",icon:"warning"})).value)return;r.data.gold=99e5,console.log("Set player gold to 9900000.");let t=100-2,n=1.042;r.data.stars=Math.round((1-Math.pow(n,t))/(1-n)*20+10),r.data.level=100,r.getLevel=()=>r.data.level,console.log("Set player level to 100"),r.data.bountyScore=100,console.log("Set player's bounty points to 100.");for(let f=0;f<99;f++)Y.giftBoxController.receiveGiftBox(null,Ae("giftBox",1));console.log("Obtained 100 conjure cubes."),r.data.win=P,console.log("Set player's wins to VERY_LARGE_NUMBER"),r.data.loss=0,console.log("Set player's losses to 0."),r.modifiers.damage=P,console.log("Enabled damage multiplier."),r.pvpHP=P,r.getMaxHearts=()=>P,console.log("PvP health obtained.");for(var o=0;o<100;o++)r.achievements.data.progress[o]=10;console.log("Obtained all achievements."),r.data.tower=100,console.log("Set tower floor to 100."),r.getMaxHearts=()=>P,r.pvpHP=P,r.data.hp=P,console.log("Maxed out PvE health."),pe(99e4),fe(),l.fire("Success!","All items added!","success"),console.log("All items added!"),r.backpack.data.mount=W(c.gameData.mount,1),console.log("Added all mounts."),me(),console.log("Added all pets."),c.gameData.pet.filter(f=>[158,166,168].includes(f.ID)).forEach(f=>{r.kennel.addPet(f.ID,P,26376,100)}),r.kennel.petTeam.forEach(f=>{f&&f.assignRandomSpells&&f.assignRandomSpells()}),console.log("Added Mythical Epics."),c.gameData.pet.filter(f=>[125,126,127,128,129,130,131,132,133].includes(f.ID)).forEach(f=>{r.kennel.addPet(f.ID,P,26376,100)}),r.kennel.petTeam.forEach(f=>{f&&f.assignRandomSpells&&f.assignRandomSpells()}),console.log("Added Legacy Epics."),c.constants.constants["GameConstants.Inactivity.LOG_OUT_TIMER_SECONDS"]=0,console.log("Inactivity Kick Disabled."),r._playerContainer.walkSpeed=20,console.log("Player walkspeed set to 20.");let d=100,p;return Array.from(c.instance.prodigy.gameContainer._inversifyContainer._bindingDictionary._map).forEach(f=>{try{c.instance.prodigy.gameContainer.get(f[0]).battleData&&(p=f[0])}catch{console.log(`Error for ${f[0]}`)}}),c.instance.prodigy.gameContainer.get(p).battleData._secureCharacterState._data.inventory.orb=Ln(c.gameData.orb,d),r.equipment.setHat(200),r.equipment.setBoots(93),r.equipment.setOutfit(161),r.equipment.setWeapon(196),M(),console.log("Character Saved."),r.appearanceChanged=!0,console.log("Appearance Refreshed."),c.instance.prodigy.open.menuCloseAll(),console.log("Popups closed."),M(),console.log("Character Saved."),console.log("Max Account Successful."),l.fire("Maxed!","Check your backpack!","success")});new m(u.inventory,"Item stacker").setClick(async()=>{let e=await b.fire("Amount","How many of every item would you like?","question");if(e.value&&(await E.fire("Are you sure you want to get all items in the game?")).value)return pe(e.value),fe(),l.fire("Success!","All items added!","success")});new m(u.inventory,"Clear inventory").setClick(async()=>{(await E.fire("Are you sure you want to clear your inventory?")).value&&(Object.keys(r.backpack.data).forEach(e=>r.backpack.data[e]=[]),l.fire("Success!","Inventory cleared.","success"))});new m(u.inventory,"Selector (Basic)").setClick(async()=>{let e=await g.fire({title:"What would you like to obtain?",input:"select",inputOptions:j,inputPlaceholder:"Select...",inputValidator:t=>t?"":"Please select which you'd like to obtain.",showCancelButton:!0}).then(async t=>{let n=parseInt(t.value),o=j[n],s=C[n];if(!o)return;let a=await b.fire("Amount","How many each object would you like?","question");a.value&&(await E.fire(`Are you sure you want to get all ${o.toLowerCase()}?`)).value&&(r.backpack.data[s]=W(c.gameData[s].filter(d=>s==="follow"?!xe.includes(d.ID):d),a.value),l.fire(`${o} Added!`,`All ${o.toLowerCase()} have been added to your inventory!`,"success"),M())})});new m(u.inventory,"Selector (Advanced)","Choose a specific object and quantity to obtain.").setClick(async()=>{let e=await g.fire({title:"What would you like to obtain?",input:"select",inputOptions:j,inputPlaceholder:"Select...",inputValidator:t=>t?"":"Please select which you'd like to obtain.",showCancelButton:!0}).then(async t=>{if(!c.gameData[C[t.value]])return;let n=[];c.gameData[C[t.value]].forEach(s=>{n.push(s.data.name)});let o=await g.fire({title:`What specific object categorized as ${j[t.value].toLowerCase()} would you like to get?`,input:"select",inputOptions:n,inputPlaceholder:"Select...",inputValidator:s=>s?"":"Please select which you'd like to get.",showCancelButton:!0}).then(async s=>{let a=parseInt(s.value);if(!c.gameData[C[t.value]][a])return;let d=await b.fire("Amount","How many of the object would you like?","question");if(!d.value)return;let p=r.backpack.data[C[t.value]].findIndex(f=>f.ID===c.gameData[C[t.value]][a].ID);return p===-1?r.backpack.data[C[t.value]].push({ID:c.gameData[C[t.value]][a].ID,N:d.value}):r.backpack.data[C[t.value]][p].N=d.value,console.log(c.gameData[C[t.value]][a].ID),M(),l.fire(`${j[t.value]} Added!`,`Your selected ${j[t.value].toLowerCase()} have been added.`,"success")})})});new m(u.inventory,"Obtain All Furniture").setClick(async()=>{let e=await b.fire("Amount","How many of each piece of furniture would you like?","question");if(e.value&&(await E.fire("Are you sure you want to get all furniture?")).value)return c.gameData.dorm.forEach(t=>r.house.data.items[t.ID]={A:[],N:e.value}),l.fire("Furniture Added!","All furniture has been added to your inventory!","success")});new m(u.inventory,"Obtain All Mounts","This gives you all of the mounts in the game.").setClick(async()=>(r.backpack.data.mount=W(c.gameData.mount,1),l.fire("Mounts Added!","All mounts have been added to your inventory!")));new m(u.inventory,"Remove item").setClick(async()=>{let e=await g.fire({title:"What category would you like to remove an item from?",input:"select",inputOptions:j,inputPlaceholder:"Select...",inputValidator:a=>a?"":"Please select which you'd like to obtain.",showCancelButton:!0});if(!c.gameData[C[e.value]])return;let t=c.gameData[C[e.value]].map(a=>a.data.name),n=await g.fire({title:`What specific object categorized as ${j[e.value].toLowerCase()} would you like to remove?`,input:"select",inputOptions:t,inputPlaceholder:"Select...",inputValidator:a=>a?"":"Please select which you'd like to get.",showCancelButton:!0});if(n=parseInt(n.value),!c.gameData[C[e.value]][n])return;let o=await b.fire("Amount","How many of the object would you like to remove?","question");if(!o.value)return;if(r.backpack.data[C[e.value]].findIndex(a=>a.ID===c.gameData[C[e.value]][n].ID)===-1){await g.fire("Item Does Not Exist",`You do not have any ${c.gameData[C[e.value]][n].name}.`,"error");return}let s=r.backpack.data[C[e.value]].findIndex(a=>a.ID===c.gameData[C[e.value]][n].ID);return r.backpack.data[C[e.value]][s].N-=parseInt(o.value),r.backpack.data[C[e.value]][s].N<=0&&r.backpack.data[C[e.value]].splice(s,1),M(),l.fire("Removed!",`Successfully removed ${o.value} ${c.gameData[C[e.value]][n].name}!`,"success")});new m(u.inventory,"Get All Gems","Adds one of each gem type to your backpack and saves.").setClick(async()=>([3,4,10,11,17].forEach(t=>{let n=r.backpack.data.key.find(o=>o.ID===t);n?n.N+=1:r.backpack.data.key.push({ID:t,N:1})}),r.appearance.updated=!0,r.updated=!0,r.saveEnabled=!0,typeof r.forceSaveCharacter=="function"&&r.forceSaveCharacter(),r.appearanceChanged=!0,r.backpack.updated=!0,l.fire("Done!","All gems added to your backpack.","success")));var Ge=!0;new k(u.location,"WASD Movement","Allows you to walk through walls or on air with WASD movement in Prodigy.").setEnabled(async()=>(Ge=!0,l.fire("Enabled!","WASD Movement is now enabled.","success"))).setDisabled(async()=>(Ge=!1,l.fire("Disabled!","WASD Movement is now disabled.","success"))).status=!0;new m(u.location,"Edit walkspeed","Lets you set your walkspeed.").setClick(async()=>{let e=await G.fire("What do you want to set your walk speed to?");if(e.value){if(r._playerContainer)r._playerContainer.walkSpeed=parseFloat(e.value)||1.5;else{let t=setInterval(()=>{r._playerContainer&&(clearInterval(t),r._playerContainer.walkSpeed=parseFloat(e.value))},100)}return l.fire("Success!",`Successfully made walk speed ${parseFloat(e.value)||1.5}!`,"success")}});var On=-1;new k(u.location,"Toggle Click Teleporting").setEnabled(async()=>(On=setInterval(()=>{try{r._playerContainer.walkSpeed=500}catch{}},16),l.fire("Success!","Successfully enabled teleport click.","success"))).setDisabled(async()=>(clearInterval(On),r._playerContainer.walkSpeed=1.5,l.fire("Success!","Successfully disabled teleport click.","success")));new m(u.location,"Teleport To Map (interactive)").setClick(async()=>{let e=g.mixin({focusConfirm:!1,showCancelButton:!0,preConfirm:()=>document.querySelector(".radioDiv[checked]")?.getAttribute("zone")}),t=document.createElement("div");t.classList.add("radioContainer");for(let p of Object.keys(Y.world.zones)){let f=document.createElement("DIV");f.classList.add("radioDiv"),f.setAttribute("zone",p),f.innerText=p,f.onclick=()=>{document.querySelectorAll(".radioDiv[checked]").forEach(I=>I.removeAttribute("checked")),f.setAttribute("checked","")},t.append(f)}let n=await e.fire({title:"Teleport Zone",html:t,customClass:{popup:"radioSwal"}});if(!n.value)return;let o=Object.keys(Y.world.zones[n.value].maps),s=await g.fire({input:"select",inputOptions:new Map(o.map(p=>[p,p])),title:"Map",text:"Which map in the zone do you want to teleport to?"});if(!s.value)return;let a=(await b.fire("Please enter the x to teleport to. (Try 500?)")).value||500,d=(await b.fire("Please enter the y to teleport to. (Try 500?)")).value||500;return Y.world.zones[n.value].teleport(s.value,a,d,{},{}),l.fire("Teleported","You have been teleported!","success")});new m(u.location,"Teleport to house by userID").setClick(async()=>{let e=(await b.fire("Please enter the userID.")).value;if(e)return Mn(e),l.fire("Teleported!","You have been teleported!","success")});new m(u.location,"Get Map Location").setClick(async()=>{let e=r.data.zone;navigator.clipboard.writeText(e).then(async function(){return console.log("Async: Copying to clipboard was successful!"),g.fire({title:"Map Location",html:`You are at
        ${e} .
        You can save this to get to the same zone.

        Your location is has also been copied to your clipboard.`,icon:"info"})},async function(t){return console.error("Async: Could not copy text: ",t),g.fire({title:"Map Location",html:`You are at
        ${e} .
        You can save this to get to the same zone.`,icon:"info"})})});new k(u.minigames,"69x Walk Speed [Dyno Dig]","Walk so fast that you're teleporting, in Dyno Dig.").setEnabled(async()=>(c.instance.game.state.states.get("DinoDig").walkSpeed=69,l.fire("Enabled!","You will now walk so fast that you're teleporting in Dyno Dig.","success"))).setDisabled(async()=>(c.instance.game.state.states.get("DinoDig").walkSpeed=1.5,l.fire("Disabled!","You will now walk at normal speed, in Dyno Dig.","success")));new m(u.minigames,"Dino Dig +100 Days","Adds 100 days to the active Dino Dig timer.").setClick(async()=>{let e=c.instance.game.state.states.get("DinoDig");return e?.timer?.addTime?(e.timer.addTime(864e7),l.fire("Done!","Added 100 days to the Dino Dig timer.","success")):g.fire("Error","You are not currently in Dino Dig.","error")});new m(u.minigames,"End Dino Dig","Instantly ends the current Dino Dig session.").setClick(async()=>{let e=c.instance.game.state.states.get("DinoDig");return e?.timer?.addTime?(e.timer.addTime(-9e15),l.fire("Done!","Dino Dig session ended.","success")):g.fire("Error","You are not currently in Dino Dig.","error")});var vt=document.createElement("button"),Ee=null;function Hn(){Ee||Ts()}function _n(){Ee&&(clearInterval(Ee),Ee=null),document.getElementById("fps-counter")?.remove()}function Ts(){vt.id="fps-counter",je?.prepend(vt),Ee=setInterval(()=>{vt.innerText=r.game.fps._framerate.toFixed(2)+" FPS"},300)}new m(u.misc,"Skip Tutorial").setClick(async()=>{let e=(t,n,o,s)=>{c.instance.prodigy.world.getZone(t).testQuest(n,o,s);try{Object.fromEntries(c.instance.game.state.states).TileScreen.process()}catch{}};e("house",2),e("academy",2),r.state.set("tutorial-0",4),r.backpack.addKeyItem(13,0),r.tutorial.data.menus[14]=[1],c.instance.prodigy.open.map(!0,[]),r.onTutorialComplete(),r.data.level=Math.max(r.data.level,5)});new k(u.beta,"FPS Counter [BETA]","Shows you a framerate counter").setEnabled(async()=>{Hn()}).setDisabled(async()=>{_n()});try{let e=null;new k(u.misc,"Unlimited Spins","Lets you spin the wheel as many times as you want!").setEnabled(async()=>(e=r.canSpin,r.canSpin=()=>!0,l.fire("Enabled!","You can now spin the wheel as many times as you want!","success"))).setDisabled(async()=>(r.canSpin=e,l.fire("Disabled!","You can now spin the wheel only when allowed.","success")))}catch(e){console.error("Unlimited Spins ERROR: "+e)}new m(u.misc,"Reset Account","Completely resets your account.").setClick(async()=>{if((await E.fire("Are you sure you want to reset your account?","This action is not reversible.")).value)return r.resetAccount(),g.fire("Reset!","Your account has been reset. Reload Prodigy for the full effect.","success")});new m(u.misc,"[Fix] Fix Battle Crash").setClick(async()=>(r.kennel.petTeam.forEach(e=>{e&&e.assignRandomSpells&&e.assignRandomSpells()}),l.fire("Success!","Fixed kennel attack bug!","success")));new m(u.misc,"[Fix] Stuck in Unfinished Tower Fix","Takes you out of an unfinished tower if you're stuck in one.").setClick(async()=>(c.instance.prodigy.world.zones.house.teleport("exit"),l.fire("Success!","You've been teleported outside of your house.","success")));new k(u.misc,"Disable Monster Encounters").setEnabled(async()=>q("GameConstants.Debug.SCALE_ENCOUNTER_DISTANCE",0)?l.fire("Enabled!","Monsters will no longer battle you.","success"):l.fire("Error","FlagProvider service not found.","error")).setDisabled(()=>(q("GameConstants.Debug.SCALE_ENCOUNTER_DISTANCE",1),l.fire("Disabled!","Monsters will now battle you.","success")));new m(u.misc,"Bobbified","Turns you into Bobby Fancywoman (level 69, specific appearance).").setClick(async()=>{if((await E.fire("Are you sure?","You will be transformed into Bobby Fancywoman.")).value)return r.name.data.firstName=44,r.name.data.middleName=754,r.name.data.lastName=882,r.data.stars=-1e22,r.data.level=69,r.appearance.setEyeColor(1),r.appearance.setFace(4),r.appearance.setHair(19,1),r.appearance.setSkinColor(1),r.equipment.setFollow(19),r.equipment.setHat(19),r.equipment.setBoots(19),r.equipment.setOutfit(19),r.equipment.setWeapon(19),l.fire("Done!","You are now Bobby Fancywoman.","success")});new m(u.pets,"Get All Pets").setClick(async()=>(await E.fire("Would you like to add all pets to your pets?")).value?(me(),l.fire("Success!","All pets have been added!","success")):console.log("Cancelled"));new m(u.pets,"Get All Legacy Epics").setClick(async()=>(await E.fire({title:"This may damage your account.",html:"Attempting to add legacy epics may damage your account.

        Warning: this does NOT save on reload — the pets will disappear after refreshing.

        Would you still like to add all legacy epics to your team?",icon:"warning"})).value?(c.gameData.pet.filter(t=>[125,126,127,128,129,130,131,132,133].includes(t.ID)).forEach(t=>{r.kennel.addPet(t.ID,P,26376,100)}),r.kennel.petTeam.forEach(t=>{t&&t.assignRandomSpells&&t.assignRandomSpells()}),l.fire("Success!","All legacy epics have been added!","success")):console.log("Cancelled"));new m(u.pets,"Get All Mythical Epics").setClick(async()=>(await E.fire({title:"Add all mythical epics?",html:"Warning: this does NOT save on reload — the pets will disappear after refreshing.

        Would you like to add all mythical epics to your pets?",icon:"warning"})).value?(c.gameData.pet.filter(t=>[158,164,165,166,167,168,169,170,171,189].includes(t.ID)).forEach(t=>{r.kennel.addPet(t.ID,P,26376,100)}),r.kennel.petTeam.forEach(t=>{t&&t.assignRandomSpells&&t.assignRandomSpells()}),l.fire("Success!","All mythical epics have been added!","success")):console.log("Cancelled"));new m(u.pets,"Clear Pets").setClick(async()=>(await E.fire("Would you like to delete all of your pets?")).value?(r.kennel.data.length=0,l.fire("Success!","Your pets have been cleared!","success")):console.log("Cancelled"));new m(u.pets,"Add Pet","Adds a pet from a list.").setClick(async()=>{let e=await g.fire({input:"select",inputOptions:new Map(c.gameData.pet.map(t=>[t.ID.toString(),`${t.ID}: ${t.data.name}`])),title:"Choose Pet",text:"Which pet do you want to obtain?"});if(e.value!==void 0)return r.kennel.addPet(e.value),r.kennel._encounterInfo._data.pets.push({firstSeenDate:Date.now(),ID:e.value,timesBattled:1,timesRescued:1}),l.fire("Success!","Your chosen pet has been added to your pets!","success")});new m(u.pets,"Uncap pet level [Client Side]","Change your pet's level to anything, even over 100. This hack won't save when you reload Prodigy.").setClick(async()=>{let e=r.kennel.petTeam.slice(0);e.shift();let t=e.map(a=>a.getName()),n=await g.fire({title:"Which pet would you like to edit?",input:"select",inputOptions:t,inputPlaceholder:"Select...",inputValidator:a=>a?"":"Please select which you'd like to obtain.",showCancelButton:!0}),o=await b.fire("Level","What would you like to set your pet's level to? (Can be set over 100)","question");if(!o.value)return;let s=o.value;return r.kennel.petTeam[parseInt(n.value)+1].getLevel=()=>Number(s),l.fire("Updated!","The level of your pet was successfully updated. Note: this hack is client-side.","success")});new m(u.pets,"Delete Pet","Delete a pet.").setClick(async()=>{let e=await Ue("Which pet do you wish to delete?");if(e!==void 0)return r.kennel.data.splice(e,1),l.fire("Successfully deleted!","The selected pet was deleted successfully.","success")});new m(u.pets,"All Pets Level 150","Replaces all pets with every pet at level 150. WARNING: Erases current pet data.").setClick(async()=>{if((await E.fire("Are you sure?","This will erase all your current pet data and replace it with every pet at level 150.")).value)try{let e=(d,p)=>Math.floor(Math.random()*(p-d+1)+d),t=(d,p)=>{let f=p.data.statHealth,I=500/1.25*Math.pow(Math.pow(1.25,.25),f-1),we=100/1.25*Math.pow(Math.pow(1.25,.25),f-1);return Math.ceil(I+(d-1)*we)},s=(d=>{if(d===1)return 0;if(d===2)return 10;let p=d-2,f=1.042;return Math.round((1-Math.pow(f,p))/(1-f)*20+10)})(150),a=c.gameData.pet;return r.kennel.data.length=0,a.forEach(d=>{r.kennel.addPet(d.ID,t(150,d),s,150)}),r.kennel._encounterInfo._data.pets=a.map(d=>({firstSeenDate:Date.now()-e(2e4,12e4),ID:d.ID,timesBattled:1,timesRescued:1,rescueAttempts:1})),r.kennel.petTeam.forEach(d=>{d&&d.assignRandomSpells&&d.assignRandomSpells()}),g.fire("Done!","All pets added at level 150. Leave the game open for ~2 minutes to fully sync.","success")}catch(e){return g.fire("Error","Failed to add pets: "+e,"error")}});new m(u.player,"Max Account").setClick(async()=>{if(!(await E.fire("Are you sure that you want to max your account?","We recommend doing this on an alt.")).value)return console.log("Cancelled");r.data.gold=99e5,console.log("Set player gold to 9900000.");let t=100-2,n=1.042;r.data.stars=Math.round((1-Math.pow(n,t))/(1-n)*20+10),r.data.level=100,r.getLevel=()=>r.data.level,console.log("Set player level to 100"),r.data.bountyScore=100,console.log("Set player's bounty points to 100.");for(let d=0;d<99;d++)Y.giftBoxController.receiveGiftBox(null,Ae("giftBox",1));console.log("Obtained 100 conjure cubes.");for(var o=0;o<100;o++)r.achievements.data.progress[o]=10;console.log("Obtained all achievements."),r.data.tower=100,console.log("Set tower floor to 100."),pe(1),fe(),l.fire("Success!","All items added!","success"),console.log("All items added!"),r.backpack.data.mount=W(c.gameData.mount,1),console.log("Added all mounts.");let s="currency",a=6969420;return r.backpack.data[s]=W(c.gameData[s].filter(d=>s==="follow"?!xe.includes(d.ID):d),a),me(),console.log("Added all pets."),r.equipment.setHat(200),r.equipment.setBoots(93),r.equipment.setOutfit(161),r.equipment.setWeapon(196),r.appearanceChanged=!0,console.log("Appearance Refreshed."),M(),console.log("Character Saved."),console.log("Max Account Successful."),l.fire("Maxed!","Check your backpack!","success")});new m(u.player,"Set Gold").setClick(async()=>{let e=await b.fire("Gold Amount","What number do you want to set your gold to?","question");if(e.value!==void 0)return e.value>1e7?l.fire("Error","Cannot have more than 10,000,000 gold.","error"):(r.data.gold=+e.value,l.fire("Success!",`You now have ${e.value} gold.`,"success"))});new m(u.player,"Set Magicoin","Set your Magicoin amount.").setClick(async()=>{let e=await b.fire("Magicoin Amount","What number do you want to set your Magicoin to?","question");if(e.value!==void 0)try{return r._secureInventory._cacheByPath.currency[27].stackable.quantity=+e.value,l.fire("Done!",`Magicoin set to ${e.value}.`,"success")}catch{return g.fire("Error","Failed to set Magicoin. The path may have changed.","error")}});new m(u.player,"Set Level").setClick(async()=>{let e=await b.fire("Level","What number do you want to set your level to?","question");if(e.value===void 0)return;if(e.value===1)return 0;let t=e.value-2,n=1.042;return r.data.stars=Math.round((1-Math.pow(n,t))/(1-n)*20+10),r.data.level=+e.value,r.getLevel=()=>r.data.level,l.fire("Success!",`You are now level ${e.value}.`,"success")});new m(u.player,"Get member stars").setClick(async()=>{let e=await b.fire("Stars","How many member stars do you want?","question");if(e.value!==void 0)return r.data.storedMemberStars=e.value,l.fire("Success!",`You have set your member stars to ${e.value}.`,"success")});new m(u.player,"Set Bounty Points").setClick(async()=>{let e=await b.fire("Bounty Points","What number do you want to set your bounty points to? (Max is 100)","question");if(e.value!==void 0)return r.data.bountyScore=Math.min(+e.value,100),l.fire("Success!",`You now have ${r.data.bountyScore} bounty point${r.data.bountyScore!=1?"s":""}.`,"success")});new m(u.player,"Set Wins").setClick(async()=>{let e=await b.fire("Wins","What number do you want to set your wins to?","question");if(e.value!==void 0)return r.data.win=+e.value,l.fire("Success!",`You have set your win${e.value!=1?"s":""} to ${e.value}.`,"success")});new m(u.player,"Set Losses").setClick(async()=>{let e=await b.fire("Losses","What number do you want to set your losses to?","question");if(e.value!==void 0)return r.data.loss=+e.value,l.fire("Success!",`You have set your loss${e.value!=1?"es":""} to ${e.value}.`,"success")});var Se=null;new k(u.player,"Toggle Membership (Client Side)").setEnabled(async()=>c.functions?.setMembership?.(!0)?(Se||(Se=r.getMemberTier?.bind(r)),r.getMemberTier=()=>103,r.appearanceChanged=!0,l.fire({icon:"success",title:"Membership enabled (cosmetic)",html:"Use Selector (Advanced) to get member-only items."})):l.fire("Error","Membership service not found.","error")).setDisabled(()=>c.functions?.setMembership?.(!1)?(Se&&(r.getMemberTier=Se,Se=null),r.appearanceChanged=!0,l.fire("Success!","You no longer have Prodigy membership!","success")):l.fire("Error","Membership service not found.","error"));new m(u.player,"Set name (Client side only)").setClick(async()=>{let e=await G.fire("What would you like to set your name to?");if(e.value)return r.getName=()=>e.value,r.appearanceChanged=!0,l.fire("Changed!","Your name was changed.")});new m(u.player,"Change Name","Change the name of your wizard.").setClick(async()=>{let e=c.gameData.name,t=document.createElement("div"),n=(a,d)=>{let p=document.createElement("select");p.classList.add("selectName");for(let f of a.entries()){let I=document.createElement("option");[I.value,I.innerText]=f,d(I.value)&&(I.selected=!0),p.options.add(I)}return p},o=(a,d)=>n(new Map(e.filter(p=>p.data.type===a).map(p=>[p.ID.toString(),p.name])),p=>d(+p));t.append(o(0,a=>a===r.name.data.firstName)),t.append(o(1,a=>a===r.name.data.middleName)),t.append(o(2,a=>a===r.name.data.lastName)),t.append(n(new Map([["null","[none]"]].concat(c.gameData.nickname.map(a=>[a.ID.toString(),a.name]))),a=>+a===r.name.data.nickname||String(r.name.data.nickname)===a));let s=await g.fire({title:"Set Player Name",focusConfirm:!1,showCancelButton:!0,html:t,preConfirm:()=>Array.prototype.slice.call(document.querySelectorAll(".selectName")).map(a=>a.options[a.selectedIndex].value)});if(s.value!==void 0)return s.value[3]==="null"&&(s.value[3]=null),[r.name.data.firstName,r.name.data.middleName,r.name.data.lastName,r.name.data.nickname]=s.value.map(a=>a&&+a),r.appearanceChanged=!0,l.fire("Name Changed!","Your name was successfully changed.","success")});new m(u.player,"Uncap player level (client side only)").setClick(async()=>{let e=await b.fire("Level","What would you like to set your level to? (Can be >100)","question");if(e.value)return localStorage.setItem("level",e.value),r.getLevel=()=>Number(e.value),l.fire("Updated!","Your level has been successfully updated","success")});new m(u.player,"Get all achievements").setClick(async()=>{for(var e=0;e<100;e++)r.achievements.data.progress[e]=10;return l.fire("Success!","Obtained all achievements!","success")});new m(u.player,"Fix Morph Crash").setClick(async()=>(r.getPlayerData().playerTransformation=void 0,r.appearanceChanged=!0,l.fire("Success!","Fixed morph crash bug.","success")));new m(u.player,"Permanent Morph","Makes Your Current Morph Last Forever.").setClick(async()=>r.data.playerTransformation?(r.data.playerTransformation.maxTime=1/0,r.data.playerTransformation.timeRemaining=1/0,l.fire("Success!","You're morph will last forever!","success")):g.fire("No Morph Active","Please use a Morph Marble and try again.","error"));new m(u.player,"Morph Player [BETA]","Morph into a pet, furnishing, or follow.").setClick(async()=>{if(!(await E.fire("This hack is in BETA","Expect bugs, and it might not work properly.")).value)return console.log("Cancelled");let e=await g.fire({title:"Which morph type?",input:"select",inputOptions:{pet:"Pet",dorm:"Furniture",follow:"Follow"},inputPlaceholder:"Morph Type",inputValidator:o=>o?"":"Please select a morph type.",showCancelButton:!0});if(!e?.value)return;let t={};c.gameData[e.value].forEach(o=>t[o.ID]=`${o.name} (${o.ID})`);let n=await g.fire({title:"Which morph?",input:"select",inputOptions:t,inputPlaceholder:"Morph ID",inputValidator:o=>o?"":"Please select a morph ID.",showCancelButton:!0});if(n.value)return r.getPlayerData().playerTransformation={transformType:e.value,transformID:n.value,maxTime:3600*1e3,timeRemaining:3600*1e3},r.appearanceChanged=!0,l.fire("Morphed!","You've been morphed.","success")});new m(u.player,"Complete Current Task In Quest","Completes current task in quest. (Use this button a lot to complete a quest.)").setClick(async()=>{let e={};Object.keys(c.instance.prodigy.world.zones).forEach(o=>{e[o]=c.instance.prodigy.world.zones[o].name});let t=(await G.fire({title:"What Quest Do You Want To Complete?",input:"select",inputOptions:e})).value;if(!t)return;let n=c.instance.prodigy.world.zones[t].getCurrentQuestID();return c.instance.prodigy.world.zones[t].completeQuest(n)?(c.instance.prodigy.world.goToZoneHub(t),l.fire("Success!",`Completed current task in the ${c.instance.prodigy.world.zones[t].name} quest successfully!`,"success")):l.fire("Could Not Complete Current Task In Quest.","There was an error completing the quest. Did you already complete it?","error")});new m(u.player,"Set Dark Tower Floor").setClick(async()=>{let e=await b.fire({title:"What floor do you want to be on, in the dark tower.",icon:"question",inputValidator:t=>t>100||t<1?`You can only be on floors from 1-100 not ${t}`:!1});if(e.value)return r.data.tower=parseInt(e.value),l.fire("Success!",`Successfully set dark tower floor to ${e}!`,"success")});new m(u.player,"Get UserID").setClick(async()=>{let e=r.userID;navigator.clipboard.writeText(e.toString()).then(function(){return console.log("Async: Copying to clipboard was successful!"),g.fire({title:"User ID",html:`Here is your User ID:
        ${e}
        You can use this for copying your account.

        Your UserID is has also been copied to your clipboard.`,icon:"info"})},function(t){return console.error("Async: Could not copy text: ",t),g.fire({title:"User ID",html:`Here is your User ID:
        ${e}
        You can use this for copying your account.`,icon:"info"})})});new m(u.player,"Copy Account","Copy Account From userID").setClick(async()=>{let e=(await b.fire("What is the userID of the account you want to copy?",void 0,"question")).value;if(!e)return;let t=await fetch(`https://api.prodigygame.com/game-api/v2/characters/${e}?fields=inventory%2Cdata%2CisMember%2Ctutorial%2Cpets%2Cencounters%2Cquests%2Cappearance%2Cequipment%2Chouse%2Cachievements%2Cstate&userID=${e}`,{headers:{Authorization:localStorage.JWT_TOKEN}});if(!t.ok)return l.fire("Error",`Failed to fetch account data: ${t.status} ${t.statusText}`,"error");let n=await t.json();if(!n[e])return l.fire("Error",`Account #${e} not found or data is invalid.`,"error");if((await E.fire("WARNING: This operation is IRREVERSIBLE!",`You are about to overwrite ALL of your character data with account #${e}. This action CANNOT be undone. The source account data has not been reviewed. -Are you absolutely sure?`)).value)try{let o=await fetch(`https://api.prodigygame.com/game-api/v3/characters/${e}`,{headers:{"Content-Type":"application/json",Authorization:localStorage.JWT_TOKEN},body:JSON.stringify({data:JSON.stringify(n[e]),userID:r.userID}),method:"POST"});return o.ok?l.fire("Success!","Copied Account Successfully! Please reload.","success"):l.fire("Error",`Failed to copy account: ${o.status} ${o.statusText}`,"error")}catch(o){return l.fire("Error",`Network error while copying account: ${o instanceof Error?o.message:"Unknown error"}`,"error")}});new p(u.player,"Set Grade").setClick(async()=>{let e=await b.fire("What number do you want to set your grade to?");if(e.value)return r.grade=parseInt(e.value),l.fire("Success",`Successfully changed grade to ${e}!`,"success")});new p(u.utility,"Close all popups","Closes all popups in Prodigy.").setClick(async()=>(c.instance.prodigy.open.menuCloseAll(),l.fire("Closed!","All open popups were closed.","success")));new p(u.utility,"Grab UserID of all players on screen","Shows you the UserID and name of every player currently shown on the screen.").setClick(async()=>{let e=he.playerList;if(Object.keys(e).length===0)return l.fire("No players found.","There are no other players on the screen.","error");let t=document.createElement("ul");for(let[n,o]of Object.entries(e)){let s="Unknown";try{s=o.nameText.textSource.source}catch{}let a=document.createElement("li");a.textContent=`uID: ${n} - ${s}`,t.append(a)}return g.fire({title:"All players on the screen:",html:t,icon:"info"})});new p(u.utility,"Save Character Locally [Local]","Saves your character locally.").setClick(async()=>(localStorage.setItem("playerData",JSON.stringify(r.getUpdatedData(!0))),l.fire("Success!","Note: Load Character will only work on this device.","success")));new p(u.utility,"Load local character [Local]","Loads your character locally.").setClick(async()=>{if(localStorage.getItem("playerData")){let e=localStorage.getItem("playerData"),t=await fetch(`https://api.prodigygame.com/game-api/v3/characters/${r.userID}`,{headers:{accept:"*/*","accept-language":"en-US,en;q=0.9",authorization:localStorage.JWT_TOKEN,"content-type":"application/json"},referrer:"https://play.prodigygame.com/",referrerPolicy:"strict-origin-when-cross-origin",body:JSON.stringify({data:e,userID:r.userID}),method:"POST",mode:"cors"});return t.ok?l.fire("Success!","Character has been successfully loaded. Reload for the changes to take effect.","success"):l.fire("Request failed.",`An error occurred while loading the character. Error code: ${t.status}`,"error")}else return l.fire("Error","No saved character.","error")});new p(u.utility,"Save Character","Helps fix bugs where not all hacks save.").setClick(async()=>($(),l.fire("Success!","Your character has been saved!","success")));new k(u.utility,"Enable menu resize","Allows you to resize the menu via dragging the bottom right corner.").setEnabled(async()=>(document.getElementById("origin-menu").style.resize="both",l.fire("Success!","Drag the bottom right corner of the menu to resize it.","success"))).setDisabled(()=>(document.getElementById("origin-menu").style.resize="none",l.fire("Success!","The menu position is now locked.","success")));new k(u.utility,"Pause Game").setEnabled(async()=>(c.network.game._paused=!0,l.fire("Success!","Successfully paused Prodigy.","success"))).setDisabled(async()=>(c.network.game._paused=!1,l.fire("Success!","Successfully resumed Prodigy.","success")));new p(u.utility,"Disable inactivity kick","Keeps you from being logged out for inactivity.").setClick(async()=>F("GameConstants.Inactivity.LOG_OUT_TIMER_SECONDS",0)?l.fire("Success!","You now will never be logged out!","success"):l.fire("Error","FlagProvider service not found.","error"));new p(u.utility,"Save Inventory","Forces a server-side save of your inventory/backpack.").setClick(async()=>{try{return r.updated=!0,r.saveEnabled=!0,r.backpack&&(r.backpack.updated=!0),typeof r.save=="function"&&await r.save(),l.fire("Saved!","Inventory saved to server.","success")}catch(e){return g.fire("Error","Failed to save inventory: "+e,"error")}});new p(u.utility,"Save Pet Data","Forces a server-side save of your pet/kennel data.").setClick(async()=>(r.kennel.updated=!0,r.updated=!0,r.saveEnabled=!0,typeof r.forceSaveCharacter=="function"&&r.forceSaveCharacter(),l.fire("Saved!","Pet data saved to server.","success")));window.addEventListener("keydown",e=>{switch(e.key){case"`":c.instance.prodigy.open.menuCloseAll();break;case"\\":(async()=>{if(!(await E.fire("Kit","Would you like to equip Celestial Gear?")).value)return console.log("Cancelled");c.player.equipment.setHat(200),c.player.equipment.setBoots(93),c.player.equipment.setOutfit(161),c.player.equipment.setWeapon(196),c.player.appearanceChanged=!0,l.fire("Success!","You are now wearing Celestial Armor and wielding a Dual Blade.","success")})();break}});async function Rn(e){for(let t=0;t<100;t++)await new Promise(n=>setTimeout(n,2)),r._playerContainer.x-=e/100}async function zn(e){for(let t=0;t<100;t++)await new Promise(n=>setTimeout(n,2)),r._playerContainer.y-=e/100}window.addEventListener("keydown",e=>{if(Ke)switch(e.key){case"w":zn(40);break;case"s":zn(-40);break;case"a":Rn(40);break;case"d":Rn(-40);break}});})(); +Are you absolutely sure?`)).value)try{let o=await fetch(`https://api.prodigygame.com/game-api/v3/characters/${e}`,{headers:{"Content-Type":"application/json",Authorization:localStorage.JWT_TOKEN},body:JSON.stringify({data:JSON.stringify(n[e]),userID:r.userID}),method:"POST"});return o.ok?l.fire("Success!","Copied Account Successfully! Please reload.","success"):l.fire("Error",`Failed to copy account: ${o.status} ${o.statusText}`,"error")}catch(o){return l.fire("Error",`Network error while copying account: ${o instanceof Error?o.message:"Unknown error"}`,"error")}});new m(u.player,"Set Grade").setClick(async()=>{let e=await b.fire("What number do you want to set your grade to?");if(e.value)return r.grade=parseInt(e.value),l.fire("Success",`Successfully changed grade to ${e}!`,"success")});new m(u.utility,"Close all popups","Closes all popups in Prodigy.").setClick(async()=>(c.instance.prodigy.open.menuCloseAll(),l.fire("Closed!","All open popups were closed.","success")));new m(u.utility,"Grab UserID of all players on screen","Shows you the UserID and name of every player currently shown on the screen.").setClick(async()=>{let e=ge.playerList;if(Object.keys(e).length===0)return l.fire("No players found.","There are no other players on the screen.","error");let t=document.createElement("ul");for(let[n,o]of Object.entries(e)){let s="Unknown";try{s=o.nameText.textSource.source}catch{}let a=document.createElement("li");a.textContent=`uID: ${n} - ${s}`,t.append(a)}return g.fire({title:"All players on the screen:",html:t,icon:"info"})});new m(u.utility,"Save Character Locally [Local]","Saves your character locally.").setClick(async()=>(localStorage.setItem("playerData",JSON.stringify(r.getUpdatedData(!0))),l.fire("Success!","Note: Load Character will only work on this device.","success")));new m(u.utility,"Load local character [Local]","Loads your character locally.").setClick(async()=>{if(localStorage.getItem("playerData")){let e=localStorage.getItem("playerData"),t=await fetch(`https://api.prodigygame.com/game-api/v3/characters/${r.userID}`,{headers:{accept:"*/*","accept-language":"en-US,en;q=0.9",authorization:localStorage.JWT_TOKEN,"content-type":"application/json"},referrer:"https://play.prodigygame.com/",referrerPolicy:"strict-origin-when-cross-origin",body:JSON.stringify({data:e,userID:r.userID}),method:"POST",mode:"cors"});return t.ok?l.fire("Success!","Character has been successfully loaded. Reload for the changes to take effect.","success"):l.fire("Request failed.",`An error occurred while loading the character. Error code: ${t.status}`,"error")}else return l.fire("Error","No saved character.","error")});new m(u.utility,"Save Character","Helps fix bugs where not all hacks save.").setClick(async()=>(M(),l.fire("Success!","Your character has been saved!","success")));new k(u.utility,"Enable menu resize","Allows you to resize the menu via dragging the bottom right corner.").setEnabled(async()=>(document.getElementById("origin-menu").style.resize="both",l.fire("Success!","Drag the bottom right corner of the menu to resize it.","success"))).setDisabled(()=>(document.getElementById("origin-menu").style.resize="none",l.fire("Success!","The menu position is now locked.","success")));new k(u.utility,"Pause Game").setEnabled(async()=>(c.network.game._paused=!0,l.fire("Success!","Successfully paused Prodigy.","success"))).setDisabled(async()=>(c.network.game._paused=!1,l.fire("Success!","Successfully resumed Prodigy.","success")));new m(u.utility,"Disable inactivity kick","Keeps you from being logged out for inactivity.").setClick(async()=>q("GameConstants.Inactivity.LOG_OUT_TIMER_SECONDS",0)?l.fire("Success!","You now will never be logged out!","success"):l.fire("Error","FlagProvider service not found.","error"));new m(u.utility,"Save Inventory","Forces a server-side save of your inventory/backpack.").setClick(async()=>{try{return r.updated=!0,r.saveEnabled=!0,r.backpack&&(r.backpack.updated=!0),typeof r.save=="function"&&await r.save(),l.fire("Saved!","Inventory saved to server.","success")}catch(e){return g.fire("Error","Failed to save inventory: "+e,"error")}});new m(u.utility,"Save Pet Data","Forces a server-side save of your pet/kennel data.").setClick(async()=>(r.kennel.updated=!0,r.updated=!0,r.saveEnabled=!0,typeof r.forceSaveCharacter=="function"&&r.forceSaveCharacter(),l.fire("Saved!","Pet data saved to server.","success")));window.addEventListener("keydown",e=>{switch(e.key){case"`":c.instance.prodigy.open.menuCloseAll();break;case"\\":(async()=>{if(!(await E.fire("Kit","Would you like to equip Celestial Gear?")).value)return console.log("Cancelled");c.player.equipment.setHat(200),c.player.equipment.setBoots(93),c.player.equipment.setOutfit(161),c.player.equipment.setWeapon(196),c.player.appearanceChanged=!0,l.fire("Success!","You are now wearing Celestial Armor and wielding a Dual Blade.","success")})();break}});async function Nn(e){for(let t=0;t<100;t++)await new Promise(n=>setTimeout(n,2)),r._playerContainer.x-=e/100}async function Rn(e){for(let t=0;t<100;t++)await new Promise(n=>setTimeout(n,2)),r._playerContainer.y-=e/100}window.addEventListener("keydown",e=>{if(Ge)switch(e.key){case"w":Rn(40);break;case"s":Rn(-40);break;case"a":Nn(40);break;case"d":Nn(-40);break}});})(); diff --git a/originGUI/src/utils/status.ts b/originGUI/src/utils/status.ts deleted file mode 100644 index 87afe7a..0000000 --- a/originGUI/src/utils/status.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Swal } from "../utils/swal"; // Import Swal - - - - - -export function statusMessage () { - - - fetch(`https://raw.githubusercontent.com/ProdigyPXP/ProdigyOrigin/master/originGUI/statusmessage.json?updated=${Date.now()}`).then(response => response.json()).then(async data => { - - const enabled = data.enabled; - - if (enabled === false) { - return console.log("Status message is disabled."); - } else { - - await Swal.fire({ - title: data.title, - html: data.html, - icon: data.icon, - }); - - } - - }); - - - -}; diff --git a/originGUI/src/utils/util.ts b/originGUI/src/utils/util.ts index e22ce96..5409d95 100644 --- a/originGUI/src/utils/util.ts +++ b/originGUI/src/utils/util.ts @@ -62,29 +62,3 @@ export const saveCharacter = () => { _.player.forceSaveCharacter(); }; -/** The URL to the assets directory */ -export const assetURL = "https://raw.githubusercontent.com/ProdigyPXP/ProdigyOrigin/master/originGUI/src/assets/"; - -/** Gets the full URL of an asset */ -export const joinAsset = (asset: string) => `${assetURL}${asset}`; - -/** Location images */ -export const locations = { - academy: joinAsset("academy.png"), - bonfire_spire: joinAsset("bonfire_spire.png"), - forest: joinAsset("forest.png"), - shipwreck_shore: joinAsset("shipwreck_shore.png"), - shiverchill: joinAsset("shiverchill.png"), - skywatch: joinAsset("skywatch.png"), - dyno: joinAsset("dyno.png"), - elemental_guardian: joinAsset("elemental_guardian.png"), - darktower: joinAsset("darktower.png"), - earthtower: joinAsset("earthtower.png"), - crystal_caverns: joinAsset("crystal_caverns.png"), - archives: joinAsset("archives.png"), - house: joinAsset("house.png"), - toyzone: joinAsset("toyzone.png"), - tower_town: joinAsset("tower_town.png"), - lamplight: joinAsset("lamplight.png") -}; - From e8778e21787dc33af1966f2f65f99a984d89dd1c Mon Sep 17 00:00:00 2001 From: Alexey Fedorov Date: Thu, 24 Sep 2026 13:55:49 -0500 Subject: [PATCH 11/11] =?UTF-8?q?release:=20v4.5.0=20=E2=80=94=20Chrome=20?= =?UTF-8?q?Web=20Store=20exclusive,=20no=20remote=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the Chrome build and packaged menu to 4.5.0, marks chrome/packaged-runtime as the CWS-only line (never merged to master; Edge/Firefox stay on 4.4.x), and rewrites the CWS privacy answers and listing copy to match: remote code = No, no storage/unlimitedStorage, no GitHub host permission, DNR limited to two packaged-image redirects. Co-Authored-By: Claude Opus 5.5 --- CLAUDE.md | 2 ++ extension/lib/version.ts | 2 +- extension/package.json | 2 +- meta/webstores/CHROME.md | 14 ++++---- meta/webstores/JUSTIFICATIONS.md | 61 ++++++++++++-------------------- originGUI/package.json | 2 +- 6 files changed, 34 insertions(+), 49 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index fe60831..33b1c39 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -10,6 +10,8 @@ Monorepo for modding online math games (formerly modding Prodigy Math Game), mai ## Critical Rules +> **Branch `chrome/packaged-runtime` is the Chrome Web Store exclusive line (v4.5.x).** It is never merged into `master`. `master` stays on the v4.4.x P-NP pipeline for Edge and Firefox. CWS listing and privacy answers for this line: `meta/webstores/CHROME.md`, `meta/webstores/JUSTIFICATIONS.md`. + 1. Use **pnpm**, never npm 2. **No force pushes**, no history rewrites 3. **esbuild** for originGUI, **Plasmo** for extension — no webpack diff --git a/extension/lib/version.ts b/extension/lib/version.ts index e8618d8..cfcbaae 100644 --- a/extension/lib/version.ts +++ b/extension/lib/version.ts @@ -1 +1 @@ -export const VERSION = "4.4.1" +export const VERSION = "4.5.0" diff --git a/extension/package.json b/extension/package.json index bfd321a..4652448 100644 --- a/extension/package.json +++ b/extension/package.json @@ -1,6 +1,6 @@ { "name": "prodigy-origin-extension", - "version": "4.4.1", + "version": "4.5.0", "private": true, "description": "Plasmo-based Play Origin browser extension", "scripts": { diff --git a/meta/webstores/CHROME.md b/meta/webstores/CHROME.md index a94038a..259a4bc 100644 --- a/meta/webstores/CHROME.md +++ b/meta/webstores/CHROME.md @@ -42,7 +42,7 @@ WHAT YOU GET (THE QUICK VERSION) — Battle helpers including instant win, auto-answer, and damage modifiers — Full inventory unlocks — Custom login background and clean UI tweaks -— Automatic, hands-off updates as the game patches +— Everything ships inside the extension — no code downloaded at runtime — Zero account risk on your end — everything runs locally in your browser ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ @@ -53,7 +53,7 @@ You install the extension. You go to math.prod·igygame.com. You log in like nor That's it. There's no separate launcher. No fake game client. No sketchy download from a forum. No file you have to manually drop into a folder somewhere. Play Origin works directly inside the official game website using the same Chrome extension framework as your password manager or ad blocker. -Under the hood, Play Origin loads the official game script straight from the game's own servers and applies a small set of community-maintained patches to it right on your device — in your own browser, never on a server — then runs the result. Those patches expose the game's internal systems to a clean, friendly menu. The patch rules are maintained automatically by the ProdigyPXP project and refreshed every couple of hours, so when the game pushes an update, the mod is usually working again before you even notice anything changed. Because the game code that actually runs is the game's own — just patched locally — there's no opaque pre-built game file being shipped to you. +Under the hood, the game loads its own official script from its own servers, completely unmodified. Play Origin never downloads, rewrites, or replaces it. The extension's own scripts, which are included in the package you install from the Chrome Web Store, run alongside the game in your browser and connect the mod menu to the game's internal systems. Nothing is fetched from anywhere else and run, and nothing runs on a server. What you install is exactly what runs. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ @@ -83,8 +83,8 @@ Teleport to any zone in the game. Skip Member-only gates. Replay quests you've a CUSTOM LOGIN PAGE Optional cosmetic touches like a custom background and a refreshed logo, so the experience feels distinct from the moment you load the page. -AUTOMATIC UPDATES -The game patches frequently. Most mod tools break the moment that happens and stay broken until someone manually fixes them, sometimes for days. Play Origin uses an automated pipeline that refreshes its patch rules every two hours — your browser picks up the new rules and re-patches the game's latest script locally, so downtime is measured in minutes, not days. +BUILT TO SURVIVE GAME UPDATES +The game patches frequently, and most mod tools break the moment that happens. Play Origin doesn't patch the game's source. It hooks into parts of the game that rarely change, so most game updates don't affect it at all. When one does, a fixed version ships through the Chrome Web Store and Chrome updates the extension for you. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ @@ -145,7 +145,7 @@ Is it free? Completely. No pro tier, no upsell, no email signup, no ads. Ever. Does it still work after a game update? -Almost always within a couple of hours. An automated pipeline refreshes the patch rules every two hours, and your browser re-patches the latest game script locally. +Usually, yes. Play Origin hooks into parts of the game that rarely change. When an update does break something, the fix ships as a new version through the Chrome Web Store, and Chrome installs it automatically. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ @@ -166,7 +166,7 @@ INSTALLATION 5. The mod menu will appear in the corner of the screen once the game finishes loading. 6. Click the menu, explore the tabs, and play the way you've always wanted to. -If anything looks off, open the Play Origin popup from your Chrome toolbar. It shows the current status and a one-click "reload" button that fixes 99 percent of problems instantly. +If anything looks off, reload the game tab. The Play Origin popup in your Chrome toolbar shows the installed version and has a one-click shortcut to open the game. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ @@ -176,7 +176,7 @@ Bug reports, feature requests, and questions go to the GitHub issue tracker at g For real-time chat with other users — including help getting set up, troubleshooting weird behavior, and sharing tips — join the community Discord linked from the GitHub page. -If something breaks after a game update, sit tight. The auto-patcher usually catches it within a couple of hours. If it doesn't, post on GitHub and someone will look at it. +If something breaks after a game update, post on GitHub. Fixes ship as a new Chrome Web Store version, and Chrome installs it for you automatically. ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ diff --git a/meta/webstores/JUSTIFICATIONS.md b/meta/webstores/JUSTIFICATIONS.md index f4e29de..401ee21 100644 --- a/meta/webstores/JUSTIFICATIONS.md +++ b/meta/webstores/JUSTIFICATIONS.md @@ -2,19 +2,21 @@ These are the answers for the Chrome Web Store "Privacy practices" tab. Each block is sized to fit its field's character limit and can be pasted in verbatim. -> **Covers v4.4.x (client-side patcher).** Starting in v4.4.0 the extension no longer -> downloads a fully pre-built patched bundle. Instead it fetches Prodigy's *own* game -> script at runtime and applies a small set of community-maintained regex patch rules -> to it **locally, in the user's browser**, caching the result. This supersedes the -> v4.3.x justifications. The new behavior adds the `unlimitedStorage` permission and -> broadens the host permission from `math.prodigygame.com` to `*://*.prodigygame.com/*`. +> **Covers v4.5.x (Chrome Web Store exclusive, branch `chrome/packaged-runtime`).** +> v4.5.0 runs no remote code. Prodigy loads its own, unmodified game script; all of +> Play Origin's JavaScript (the game hooks and the mod menu) ships inside the package. +> Nothing is fetched and executed, nothing is patched in source, and Prodigy's CSP is +> left intact. Compared with v4.4.x this drops the `storage` and `unlimitedStorage` +> permissions, the `raw.githubusercontent.com` host permission, the game-script BLOCK +> rule and the CSP-stripping rule, and changes "Are you using remote code?" to **No**. +> Edge and Firefox stay on the v4.4.x pipeline (master); their justifications live there. ## Single purpose description > Field limit: 1,000 characters ``` -Play Origin injects an in-game mod menu into Prodigy Math Game (math.prodigygame.com). Its single purpose is to enhance that one game: the menu unlocks content, lets players mod their own levels, pets, and inventory, and provides battle helpers. Everything the extension does serves this goal — giving players control over a game that otherwise locks most of its content. It does this by patching Prodigy's own game script locally in the browser, never by reading or modifying any other site. +Play Origin adds an in-game mod menu to Prodigy Math Game (math.prodigygame.com). Its single purpose is to enhance that one game: the menu unlocks content, lets players mod their own levels, pets, and inventory, and provides battle helpers. Everything the extension does serves this goal. It works by running packaged scripts alongside Prodigy's own, unmodified game code on the game page, and it never reads or modifies any other site. ``` ## Permission justification — `scripting` @@ -22,39 +24,23 @@ Play Origin injects an in-game mod menu into Prodigy Math Game (math.prodigygame > Field limit: 1,000 characters ``` -The scripting permission registers a MAIN-world content script on math.prodigygame.com via chrome.scripting.registerContentScripts. It needs the MAIN world — not an isolated content script — because it overrides native DOM methods (Document.createElement, Node.appendChild, Node.insertBefore, Element.append, Element.setAttribute) to catch the exact moment Prodigy's own game.min.js script tag is inserted, neutralize it, and inject the locally-patched bundle in its place. Those prototype overrides only take effect in the page's own JavaScript context; an isolated-world script cannot patch the page's prototype chain or reach the live game-engine objects the mod menu binds to. The extension framework (Plasmo) registers the MAIN-world script from the background service worker, which is what requires this permission. No other scripting API is used. -``` +The extension framework (Plasmo) registers two content scripts in the page's MAIN world on math.prodigygame.com via chrome.scripting.registerContentScripts, which is what requires this permission. Both scripts are part of the extension package; no code is downloaded. -## Permission justification — `declarativeNetRequest` +1. A runtime script at document_start. It observes the game's own modules as they load (by wrapping Object.defineProperty) and adds small wrappers around a few of the game's methods, such as answering a question automatically when the player turns that option on. -> Field limit: 1,000 characters +2. The mod menu UI at document_idle, started once the game is ready. +They must run in the MAIN world because they work with the live objects of Prodigy's JavaScript engine, which an isolated-world content script cannot reach. No other scripting API is used. ``` -The declarativeNetRequest permission drives a small set of static rules, all scoped to prodigygame.com, registered at install via updateDynamicRules: - -1. BLOCK the original game.min.js request from Prodigy's code.prodigygame.com CDN, so the original and the locally-patched build do not both execute and conflict. - -2. MODIFY_HEADERS to strip the Content-Security-Policy and X-Frame-Options response headers on prodigygame.com page frames, so the patched bundle and the mod menu UI can be injected without being blocked by Prodigy's CSP. -3 and 4. REDIRECT the login-screen background image and logo to the extension's own equivalents (a cosmetic re-skin) hosted in the public ProdigyPXP GitHub repository. - -The rules match only on URL patterns under prodigygame.com. No browsing history or request content is read, and no other site is affected. -``` - -## Permission justification — `storage` +## Permission justification — `declarativeNetRequest` > Field limit: 1,000 characters ``` -The storage permission persists data locally between sessions via chrome.storage.local. Its main job is caching the locally-patched game bundle: the background service worker fetches Prodigy's own game script, applies the patch rules, and stores the result — keyed by the game's client version and a hash of the patch manifest. On later page loads it serves the cached build instead of re-fetching and re-patching the whole script on every navigation, and rebuilds automatically when either the game version or the patch rules change. It also stores two optional developer-override URLs (originManifestUrl, originGuiUrl) so advanced users can point the extension at a custom build or a fork. Everything is stored locally — nothing is synced and nothing leaves the user's machine. No personal data is stored: the cached content is derived entirely from Prodigy's own publicly served script and the extension's public patch rules. -``` - -## Permission justification — `unlimitedStorage` - -> Field limit: 1,000 characters +The declarativeNetRequest permission drives two REDIRECT rules, registered at install via updateDynamicRules. They swap the game's login-screen background image and logo for Play Origin artwork, a purely cosmetic re-skin. Both rules redirect to images packaged inside the extension (extensionPath, declared in web_accessible_resources for prodigygame.com only). -``` -The unlimitedStorage permission is needed because the cached patched bundle in chrome.storage.local is a full, minified game script that can exceed the default storage quota. Prodigy's game.min.js is a large production JavaScript bundle; after the extension fetches it and applies the patch rules, the resulting build is stored so it does not have to be re-fetched and re-patched on every page load. Without unlimitedStorage the cache write would fail whenever the patched bundle is larger than the default quota, forcing a full rebuild on every single navigation and defeating the cache entirely. No personal data is stored under this quota — the only content written is the patched bundle derived from Prodigy's own publicly served script, plus two short configuration URLs. +The rules match only two image URL patterns under prodigygame.com. They do not block requests, do not modify headers, do not touch scripts, and do not read browsing history or request content. No other site is affected. ``` ## Host permission justification @@ -62,19 +48,16 @@ The unlimitedStorage permission is needed because the cached patched bundle in c > Field limit: 1,000 characters ``` -Host permission for prodigygame.com (*://*.prodigygame.com/*) is required because Prodigy Math Game runs across several prodigygame.com subdomains and the extension's whole purpose is to modify that one game. It is used to inject the mod menu content script on the game page (math.prodigygame.com), to scope the declarativeNetRequest rules to the game's own requests (blocking game.min.js on code.prodigygame.com, stripping CSP headers, re-skinning the login image), and for the background service worker to fetch Prodigy's own original game.min.js so it can be patched locally. Host permission for raw.githubusercontent.com is required so the extension can fetch its patch manifest (regex patch rules) and its mod menu UI bundle from the public ProdigyPXP GitHub repositories at runtime. No other hosts are accessed, and no user data is sent to either domain — both are used purely for read-only fetches and local script injection. +Host permission for prodigygame.com (*://*.prodigygame.com/*) is required because Prodigy Math Game is served across several prodigygame.com subdomains and the extension's whole purpose is to modify that one game. It is used to run the packaged content scripts on the game page (math.prodigygame.com) and to apply the two cosmetic image redirects to the game's own login background (cdn.prodigygame.com) and logo (code.prodigygame.com). No other hosts are requested. The extension sends no user data anywhere and does not fetch any code. ``` ## Remote code justification -> Are you using remote code? **Yes** — Field limit: 1,000 characters - -``` -Play Origin does not download a pre-built patched bundle. It fetches two things and applies patches locally: +> Are you using remote code? **No** -1. A patch manifest — a JSON file from the extension's own public GitHub repo (raw.githubusercontent.com, ProdigyPXP): regex find/replace rules plus a small loader prefix/suffix, not executable code. Example: unlock a feature getter so it returns true. +No justification is required when answering No. For reviewers' reference: every script the extension executes (`runtime.*.js`, `menu.*.js`, the popup and the background service worker) is in the submitted package. The extension contains no `eval`, no `new Function`, and no code loaded from a URL. The only network requests the mod menu makes are JSON calls to Prodigy's own API (`api.prodigygame.com`) to save and load the player's character. -2. Prodigy's own game.min.js — fetched from code.prodigygame.com by the background service worker, the same script its CDN serves every player. A DNR rule blocks it in the tab; the worker fetches it independently because service-worker fetches aren't subject to the extension's DNR rules. +## Data usage -The worker patches it locally and caches the result in chrome.storage.local; the MAIN-world script injects it via the DOM. The mod menu UI is a separate pre-built bundle from the same repo, run in the page. Prodigy updates often, so a pipeline refreshes the manifest every few hours. No user data is sent. -``` +- Collects no user data. No analytics, no telemetry, no remote logging. +- Stores nothing: the extension requests no storage permission. diff --git a/originGUI/package.json b/originGUI/package.json index 179eeb1..bb92f57 100644 --- a/originGUI/package.json +++ b/originGUI/package.json @@ -1,6 +1,6 @@ { "name": "origingui", - "version": "4.4.1", + "version": "4.5.0", "description": "Play Origin mod menu", "main": "dist/bundle.js", "scripts": {