From b08126d745633e06454d25f5ffdb7dfb54c606f8 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Thu, 28 Dec 2023 18:54:30 +1100 Subject: [PATCH] Radical JS runtime overhaul. New @wailsio/runtime package --- v3/internal/runtime/README.md | 2 +- v3/internal/runtime/Taskfile.yaml | 72 +- v3/internal/runtime/assets.go | 5 + v3/internal/runtime/assets_dev.go | 5 + .../desktop/@wailsio/runtime/application.js | 46 + .../desktop/{ => @wailsio/runtime}/browser.js | 9 +- .../runtime/desktop/@wailsio/runtime/calls.js | 123 +++ .../desktop/@wailsio/runtime/clipboard.js | 35 + .../{ => @wailsio/runtime}/contextmenu.js | 17 +- .../desktop/@wailsio/runtime/dialogs.js | 138 +++ .../desktop/{ => @wailsio/runtime}/drag.js | 86 +- .../desktop/@wailsio/runtime/events.js | 134 +++ .../{ => @wailsio/runtime}/events.test.js | 2 + .../desktop/{ => @wailsio/runtime}/flags.js | 6 + .../runtime/desktop/@wailsio/runtime/index.js | 56 ++ .../{api => @wailsio/runtime}/package.json | 4 +- .../desktop/{ => @wailsio/runtime}/runtime.js | 40 +- .../desktop/{ => @wailsio/runtime}/screens.js | 25 +- .../desktop/@wailsio/runtime/system.js | 118 +++ .../{api => @wailsio/runtime}/types.d.ts | 0 .../desktop/@wailsio/runtime/window.js | 122 +++ .../desktop/{ => @wailsio/runtime}/wml.js | 54 +- v3/internal/runtime/desktop/README.md | 7 +- v3/internal/runtime/desktop/api/README.md | 363 ------- .../runtime/desktop/api/application.js | 35 - v3/internal/runtime/desktop/api/browser.js | 24 - v3/internal/runtime/desktop/api/clipboard.js | 31 - v3/internal/runtime/desktop/api/dialogs.js | 75 -- .../runtime/desktop/api/event_types.js | 178 ---- v3/internal/runtime/desktop/api/events.js | 74 -- v3/internal/runtime/desktop/api/index.js | 32 - v3/internal/runtime/desktop/api/screens.js | 38 - v3/internal/runtime/desktop/api/window.js | 159 --- v3/internal/runtime/desktop/application.js | 43 - v3/internal/runtime/desktop/calls.js | 107 -- v3/internal/runtime/desktop/clipboard.js | 33 - v3/internal/runtime/desktop/dialogs.js | 129 --- v3/internal/runtime/desktop/events.js | 194 ---- v3/internal/runtime/desktop/invoke.js | 20 - v3/internal/runtime/desktop/main.js | 58 +- v3/internal/runtime/desktop/system.js | 25 - v3/internal/runtime/desktop/window.js | 228 ----- v3/internal/runtime/runtime.js | 1 + v3/internal/runtime/runtime_debug.js | 814 +++++++++++++++ v3/internal/runtime/runtime_debug_darwin.go | 8 - .../runtime/runtime_debug_desktop_darwin.js | 873 ---------------- .../runtime/runtime_debug_desktop_linux.js | 873 ---------------- .../runtime/runtime_debug_desktop_windows.js | 935 ------------------ v3/internal/runtime/runtime_debug_linux.go | 8 - v3/internal/runtime/runtime_debug_windows.go | 8 - .../runtime/runtime_production_darwin.go | 8 - .../runtime_production_desktop_darwin.js | 1 - .../runtime_production_desktop_linux.js | 1 - .../runtime_production_desktop_windows.js | 1 - .../runtime/runtime_production_linux.go | 8 - .../runtime/runtime_production_windows.go | 8 - v3/pkg/application/application.go | 7 + v3/pkg/application/environment.go | 6 + v3/pkg/application/messageprocessor.go | 16 +- v3/pkg/application/messageprocessor_system.go | 3 + v3/pkg/application/webview_window.go | 4 +- 61 files changed, 1809 insertions(+), 4726 deletions(-) create mode 100644 v3/internal/runtime/desktop/@wailsio/runtime/application.js rename v3/internal/runtime/desktop/{ => @wailsio/runtime}/browser.js (71%) create mode 100644 v3/internal/runtime/desktop/@wailsio/runtime/calls.js create mode 100644 v3/internal/runtime/desktop/@wailsio/runtime/clipboard.js rename v3/internal/runtime/desktop/{ => @wailsio/runtime}/contextmenu.js (90%) create mode 100644 v3/internal/runtime/desktop/@wailsio/runtime/dialogs.js rename v3/internal/runtime/desktop/{ => @wailsio/runtime}/drag.js (73%) create mode 100644 v3/internal/runtime/desktop/@wailsio/runtime/events.js rename v3/internal/runtime/desktop/{ => @wailsio/runtime}/events.test.js (99%) rename v3/internal/runtime/desktop/{ => @wailsio/runtime}/flags.js (84%) create mode 100644 v3/internal/runtime/desktop/@wailsio/runtime/index.js rename v3/internal/runtime/desktop/{api => @wailsio/runtime}/package.json (82%) rename v3/internal/runtime/desktop/{ => @wailsio/runtime}/runtime.js (81%) rename v3/internal/runtime/desktop/{ => @wailsio/runtime}/screens.js (53%) create mode 100644 v3/internal/runtime/desktop/@wailsio/runtime/system.js rename v3/internal/runtime/desktop/{api => @wailsio/runtime}/types.d.ts (100%) create mode 100644 v3/internal/runtime/desktop/@wailsio/runtime/window.js rename v3/internal/runtime/desktop/{ => @wailsio/runtime}/wml.js (70%) delete mode 100644 v3/internal/runtime/desktop/api/README.md delete mode 100644 v3/internal/runtime/desktop/api/application.js delete mode 100644 v3/internal/runtime/desktop/api/browser.js delete mode 100644 v3/internal/runtime/desktop/api/clipboard.js delete mode 100644 v3/internal/runtime/desktop/api/dialogs.js delete mode 100644 v3/internal/runtime/desktop/api/event_types.js delete mode 100644 v3/internal/runtime/desktop/api/events.js delete mode 100644 v3/internal/runtime/desktop/api/index.js delete mode 100644 v3/internal/runtime/desktop/api/screens.js delete mode 100644 v3/internal/runtime/desktop/api/window.js delete mode 100644 v3/internal/runtime/desktop/application.js delete mode 100644 v3/internal/runtime/desktop/calls.js delete mode 100644 v3/internal/runtime/desktop/clipboard.js delete mode 100644 v3/internal/runtime/desktop/dialogs.js delete mode 100644 v3/internal/runtime/desktop/events.js delete mode 100644 v3/internal/runtime/desktop/invoke.js delete mode 100644 v3/internal/runtime/desktop/system.js delete mode 100644 v3/internal/runtime/desktop/window.js create mode 100644 v3/internal/runtime/runtime.js create mode 100644 v3/internal/runtime/runtime_debug.js delete mode 100644 v3/internal/runtime/runtime_debug_darwin.go delete mode 100644 v3/internal/runtime/runtime_debug_desktop_darwin.js delete mode 100644 v3/internal/runtime/runtime_debug_desktop_linux.js delete mode 100644 v3/internal/runtime/runtime_debug_desktop_windows.js delete mode 100644 v3/internal/runtime/runtime_debug_linux.go delete mode 100644 v3/internal/runtime/runtime_debug_windows.go delete mode 100644 v3/internal/runtime/runtime_production_darwin.go delete mode 100644 v3/internal/runtime/runtime_production_desktop_darwin.js delete mode 100644 v3/internal/runtime/runtime_production_desktop_linux.js delete mode 100644 v3/internal/runtime/runtime_production_desktop_windows.js delete mode 100644 v3/internal/runtime/runtime_production_linux.go delete mode 100644 v3/internal/runtime/runtime_production_windows.go create mode 100644 v3/pkg/application/environment.go diff --git a/v3/internal/runtime/README.md b/v3/internal/runtime/README.md index f6c2f249b34..50d5d5e6327 100644 --- a/v3/internal/runtime/README.md +++ b/v3/internal/runtime/README.md @@ -1,3 +1,3 @@ # Runtime -To rebuild the runtime run `task build-runtime` or if you have Wails v3 CLI, you can use `wails task build-runtime`. +To rebuild the runtime run `task build-runtime` or if you have Wails v3 CLI, you can use `wails3 task build-runtime`. diff --git a/v3/internal/runtime/Taskfile.yaml b/v3/internal/runtime/Taskfile.yaml index 0e0f7c2b622..2fd53fbb9b5 100644 --- a/v3/internal/runtime/Taskfile.yaml +++ b/v3/internal/runtime/Taskfile.yaml @@ -21,82 +21,18 @@ tasks: build:debug: internal: true cmds: - - npx esbuild desktop/main.js --bundle --tree-shaking=true --sourcemap=inline --outfile=runtime_debug_desktop_{{.PLATFORM}}.js --define:DEBUG=true --define:WINDOWS={{.WINDOWS}} --define:DARWIN={{.DARWIN}} --define:LINUX={{.LINUX}} --define:PLATFORM={{.PLATFORM}} --define:INVOKE={{.INVOKE}} - - build:debug:windows: - cmds: - - task: build:debug - vars: - WINDOWS: true - DARWIN: false - LINUX: false - PLATFORM: windows - INVOKE: "chrome.webview.postMessage" - - build:debug:linux: - cmds: - - task: build:debug - vars: - WINDOWS: false - DARWIN: false - LINUX: true - PLATFORM: linux - INVOKE: "webkit.messageHandlers.external.postMessage" - - build:debug:darwin: - cmds: - - task: build:debug - vars: - WINDOWS: false - DARWIN: true - LINUX: false - PLATFORM: darwin - INVOKE: "webkit.messageHandlers.external.postMessage" + - npx esbuild@latest desktop/main.js --bundle --tree-shaking=true --sourcemap=inline --outfile=runtime_debug.js --define:DEBUG=true build:production: internal: true cmds: - - npx esbuild desktop/main.js --bundle --tree-shaking=true --minify --outfile=runtime_production_desktop_{{.PLATFORM}}.js --define:DEBUG=false --define:WINDOWS={{.WINDOWS}} --define:DARWIN={{.DARWIN}} --define:LINUX={{.LINUX}} --define:PLATFORM={{.PLATFORM}} --define:INVOKE={{.INVOKE}} - - build:production:windows: - cmds: - - task: build:production - vars: - WINDOWS: true - DARWIN: false - LINUX: false - PLATFORM: windows - INVOKE: "chrome.webview.postMessage" - - build:production:linux: - cmds: - - task: build:production - vars: - WINDOWS: false - DARWIN: false - LINUX: true - PLATFORM: linux - INVOKE: "webkit.messageHandlers.external.postMessage" - - build:production:darwin: - cmds: - - task: build:production - vars: - WINDOWS: false - DARWIN: true - LINUX: false - PLATFORM: darwin - INVOKE: "webkit.messageHandlers.external.postMessage" + - npx esbuild@latest desktop/main.js --bundle --tree-shaking=true --minify --outfile=runtime.js --drop:console build:all: internal: true deps: - - build:debug:windows - - build:debug:linux - - build:debug:darwin - - build:production:windows - - build:production:linux - - build:production:darwin + - build:debug + - build:production cmds: - cmd: echo "Build Complete." diff --git a/v3/internal/runtime/assets.go b/v3/internal/runtime/assets.go index fb3f09ebe66..5d63f2c4410 100644 --- a/v3/internal/runtime/assets.go +++ b/v3/internal/runtime/assets.go @@ -2,6 +2,11 @@ package runtime +import _ "embed" + +//go:embed runtime.js +var DesktopRuntime []byte + var RuntimeAssetsBundle = &RuntimeAssets{ runtimeDesktopJS: DesktopRuntime, } diff --git a/v3/internal/runtime/assets_dev.go b/v3/internal/runtime/assets_dev.go index c5e5ffe7d5c..ef12f467f98 100644 --- a/v3/internal/runtime/assets_dev.go +++ b/v3/internal/runtime/assets_dev.go @@ -2,6 +2,11 @@ package runtime +import _ "embed" + +//go:embed runtime_debug.js +var DesktopRuntime []byte + var RuntimeAssetsBundle = &RuntimeAssets{ runtimeDesktopJS: DesktopRuntime, } diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/application.js b/v3/internal/runtime/desktop/@wailsio/runtime/application.js new file mode 100644 index 00000000000..88028862cbb --- /dev/null +++ b/v3/internal/runtime/desktop/@wailsio/runtime/application.js @@ -0,0 +1,46 @@ +/* + _ __ _ __ +| | / /___ _(_) /____ +| | /| / / __ `/ / / ___/ +| |/ |/ / /_/ / / (__ ) +|__/|__/\__,_/_/_/____/ +The electron alternative for Go +(c) Lea Anthony 2019-present +*/ + +/* jshint esversion: 9 */ + +import { newRuntimeCallerWithID, objectNames } from "./runtime"; +const call = newRuntimeCallerWithID(objectNames.Application); + +const HideMethod = 0; +const ShowMethod = 1; +const QuitMethod = 2; + +/** + * Hides a certain method by calling the HideMethod function. + * + * @return {Promise} + * + */ +export function Hide() { + return call(HideMethod); +} + +/** + * Calls the ShowMethod and returns the result. + * + * @return {Promise} + */ +export function Show() { + return call(ShowMethod); +} + +/** + * Calls the QuitMethod to terminate the program. + * + * @return {Promise} + */ +export function Quit() { + return call(QuitMethod); +} diff --git a/v3/internal/runtime/desktop/browser.js b/v3/internal/runtime/desktop/@wailsio/runtime/browser.js similarity index 71% rename from v3/internal/runtime/desktop/browser.js rename to v3/internal/runtime/desktop/@wailsio/runtime/browser.js index 4fa8b66a87b..64d80c9861a 100644 --- a/v3/internal/runtime/desktop/browser.js +++ b/v3/internal/runtime/desktop/@wailsio/runtime/browser.js @@ -9,17 +9,16 @@ The electron alternative for Go */ /* jshint esversion: 9 */ - import {newRuntimeCallerWithID, objectNames} from "./runtime"; -let call = newRuntimeCallerWithID(objectNames.Browser); - -let BrowserOpenURL = 0; +const call = newRuntimeCallerWithID(objectNames.Browser, ''); +const BrowserOpenURL = 0; /** * Open a browser window to the given URL * @param {string} url - The URL to open + * @returns {Promise} */ export function OpenURL(url) { - void call(BrowserOpenURL, {url}); + return call(BrowserOpenURL, {url}); } diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/calls.js b/v3/internal/runtime/desktop/@wailsio/runtime/calls.js new file mode 100644 index 00000000000..a4add6bc4f8 --- /dev/null +++ b/v3/internal/runtime/desktop/@wailsio/runtime/calls.js @@ -0,0 +1,123 @@ +/* + _ __ _ __ +| | / /___ _(_) /____ +| | /| / / __ `/ / / ___/ +| |/ |/ / /_/ / / (__ ) +|__/|__/\__,_/_/_/____/ +The electron alternative for Go +(c) Lea Anthony 2019-present +*/ + +/* jshint esversion: 9 */ +import { newRuntimeCallerWithID, objectNames } from "./runtime"; +import { nanoid } from 'nanoid/non-secure'; + +const CallBinding = 0; +const call = newRuntimeCallerWithID(objectNames.Call, ''); +let callResponses = new Map(); + +window._wails = window._wails || {}; +window._wails.callCallback = resultHandler; +window._wails.callErrorCallback = errorHandler; + +function generateID() { + let result; + do { + result = nanoid(); + } while (callResponses.has(result)); + return result; +} + +export function resultHandler(id, data, isJSON) { + const promiseHandler = getAndDeleteResponse(id); + if (promiseHandler) { + promiseHandler.resolve(isJSON ? JSON.parse(data) : data); + } +} + +export function errorHandler(id, message) { + const promiseHandler = getAndDeleteResponse(id); + if (promiseHandler) { + promiseHandler.reject(message); + } +} + +function getAndDeleteResponse(id) { + const response = callResponses.get(id); + callResponses.delete(id); + return response; +} + +function callBinding(type, options = {}) { + return new Promise((resolve, reject) => { + const id = generateID(); + options["call-id"] = id; + callResponses.set(id, { resolve, reject }); + call(type, options).catch((error) => { + reject(error); + callResponses.delete(id); + }); + }); +} + +/** + * Call method. + * + * @param {Object} options - The options for the method. + * @returns {Object} - The result of the call. + */ +export function Call(options) { + return callBinding(CallBinding, options); +} + +/** + * Executes a method by name. + * + * @param {string} name - The name of the method in the format 'package.struct.method'. + * @param {...*} args - The arguments to pass to the method. + * @throws {Error} If the name is not a string or is not in the correct format. + * @returns {*} The result of the method execution. + */ +export function ByName(name, ...args) { + if (typeof name !== "string" || name.split(".").length !== 3) { + throw new Error("CallByName requires a string in the format 'package.struct.method'"); + } + let [packageName, structName, methodName] = name.split("."); + return callBinding(CallBinding, { + packageName, + structName, + methodName, + args + }); +} + +/** + * Calls a method by its ID with the specified arguments. + * + * @param {string} methodID - The ID of the method to call. + * @param {...*} args - The arguments to pass to the method. + * @return {*} - The result of the method call. + */ +export function ByID(methodID, ...args) { + return callBinding(CallBinding, { + methodID, + args + }); +} + +/** + * Calls a method on a plugin. + * + * @param {string} pluginName - The name of the plugin. + * @param {string} methodName - The name of the method to call. + * @param {...*} args - The arguments to pass to the method. + * @returns {*} - The result of the method call. + */ +export function Plugin(pluginName, methodName, ...args) { + return callBinding(CallBinding, { + packageName: "wails-plugins", + structName: pluginName, + methodName, + args + }); +} diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/clipboard.js b/v3/internal/runtime/desktop/@wailsio/runtime/clipboard.js new file mode 100644 index 00000000000..15cfc518a46 --- /dev/null +++ b/v3/internal/runtime/desktop/@wailsio/runtime/clipboard.js @@ -0,0 +1,35 @@ +/* + _ __ _ __ +| | / /___ _(_) /____ +| | /| / / __ `/ / / ___/ +| |/ |/ / /_/ / / (__ ) +|__/|__/\__,_/_/_/____/ +The electron alternative for Go +(c) Lea Anthony 2019-present +*/ + +/* jshint esversion: 9 */ + +import {newRuntimeCallerWithID, objectNames} from "./runtime"; + +const call = newRuntimeCallerWithID(objectNames.Clipboard, ''); +const ClipboardSetText = 0; +const ClipboardText = 1; + +/** + * Sets the text to the Clipboard. + * + * @param {string} text - The text to be set to the Clipboard. + * @return {Promise} - A Promise that resolves when the operation is successful. + */ +export function SetText(text) { + return call(ClipboardSetText, {text}); +} + +/** + * Get the Clipboard text + * @returns {Promise} A promise that resolves with the text from the Clipboard. + */ +export function Text() { + return call(ClipboardText); +} diff --git a/v3/internal/runtime/desktop/contextmenu.js b/v3/internal/runtime/desktop/@wailsio/runtime/contextmenu.js similarity index 90% rename from v3/internal/runtime/desktop/contextmenu.js rename to v3/internal/runtime/desktop/@wailsio/runtime/contextmenu.js index 9788a211820..93516543599 100644 --- a/v3/internal/runtime/desktop/contextmenu.js +++ b/v3/internal/runtime/desktop/@wailsio/runtime/contextmenu.js @@ -1,8 +1,19 @@ -import {newRuntimeCallerWithID, objectNames} from "./runtime"; +/* + _ __ _ __ +| | / /___ _(_) /____ +| | /| / / __ `/ / / ___/ +| |/ |/ / /_/ / / (__ ) +|__/|__/\__,_/_/_/____/ +The electron alternative for Go +(c) Lea Anthony 2019-present +*/ -let call = newRuntimeCallerWithID(objectNames.ContextMenu); +/* jshint esversion: 9 */ + +import {newRuntimeCallerWithID, objectNames} from "./runtime"; -let ContextMenuOpen = 0; +const call = newRuntimeCallerWithID(objectNames.ContextMenu, ''); +const ContextMenuOpen = 0; function openContextMenu(id, x, y, data) { void call(ContextMenuOpen, {id, x, y, data}); diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/dialogs.js b/v3/internal/runtime/desktop/@wailsio/runtime/dialogs.js new file mode 100644 index 00000000000..6158484ed9b --- /dev/null +++ b/v3/internal/runtime/desktop/@wailsio/runtime/dialogs.js @@ -0,0 +1,138 @@ +/* + _ __ _ __ +| | / /___ _(_) /____ +| | /| / / __ `/ / / ___/ +| |/ |/ / /_/ / / (__ ) +|__/|__/\__,_/_/_/____/ +The electron alternative for Go +(c) Lea Anthony 2019-present +*/ + +/* jshint esversion: 9 */ + +/** + * @typedef {import("./types").MessageDialogOptions} MessageDialogOptions + * @typedef {import("./types").OpenDialogOptions} OpenDialogOptions + * @typedef {import("./types").SaveDialogOptions} SaveDialogOptions + */ + +import {newRuntimeCallerWithID, objectNames} from "./runtime"; + +import { nanoid } from 'nanoid/non-secure'; + +// Define constants from the `methods` object in Title Case +const DialogInfo = 0; +const DialogWarning = 1; +const DialogError = 2; +const DialogQuestion = 3; +const DialogOpenFile = 4; +const DialogSaveFile = 5; + +const call = newRuntimeCallerWithID(objectNames.Dialog, ''); +const dialogResponses = new Map(); + +/** + * Generates a unique id that is not present in dialogResponses. + * @returns {string} unique id + */ +function generateID() { + let result; + do { + result = nanoid(); + } while (dialogResponses.has(result)); + return result; +} + +/** + * Shows a dialog of specified type with the given options. + * @param {number} type - type of dialog + * @param {object} options - options for the dialog + * @returns {Promise} promise that resolves with result of dialog + */ +function dialog(type, options = {}) { + const id = generateID(); + options["dialog-id"] = id; + return new Promise((resolve, reject) => { + dialogResponses.set(id, {resolve, reject}); + call(type, options).catch((error) => { + reject(error); + dialogResponses.delete(id); + }); + }); +} + +/** + * Handles the callback from a dialog. + * + * @param {string} id - The ID of the dialog response. + * @param {string} data - The data received from the dialog. + * @param {boolean} isJSON - Flag indicating whether the data is in JSON format. + * + * @return {undefined} + */ +export function dialogCallback(id, data, isJSON) { + let p = dialogResponses.get(id); + if (p) { + if (isJSON) { + p.resolve(JSON.parse(data)); + } else { + p.resolve(data); + } + dialogResponses.delete(id); + } +} + +/** + * Callback function for handling errors in dialog. + * + * @param {string} id - The id of the dialog response. + * @param {string} message - The error message. + * + * @return {void} + */ +export function dialogErrorCallback(id, message) { + let p = dialogResponses.get(id); + if (p) { + p.reject(message); + dialogResponses.delete(id); + } +} + + +// Replace `methods` with constants in Title Case + +/** + * @param {MessageDialogOptions} options - Dialog options + * @returns {Promise} - The label of the button pressed + */ +export const Info = (options) => dialog(DialogInfo, options); + +/** + * @param {MessageDialogOptions} options - Dialog options + * @returns {Promise} - The label of the button pressed + */ +export const Warning = (options) => dialog(DialogWarning, options); + +/** + * @param {MessageDialogOptions} options - Dialog options + * @returns {Promise} - The label of the button pressed + */ +export const Error = (options) => dialog(DialogError, options); + +/** + * @param {MessageDialogOptions} options - Dialog options + * @returns {Promise} - The label of the button pressed + */ +export const Question = (options) => dialog(DialogQuestion, options); + +/** + * @param {OpenDialogOptions} options - Dialog options + * @returns {Promise} Returns selected file or list of files. Returns blank string if no file is selected. + */ +export const OpenFile = (options) => dialog(DialogOpenFile, options); + +/** + * @param {SaveDialogOptions} options - Dialog options + * @returns {Promise} Returns the selected file. Returns blank string if no file is selected. + */ +export const SaveFile = (options) => dialog(DialogSaveFile, options); diff --git a/v3/internal/runtime/desktop/drag.js b/v3/internal/runtime/desktop/@wailsio/runtime/drag.js similarity index 73% rename from v3/internal/runtime/desktop/drag.js rename to v3/internal/runtime/desktop/@wailsio/runtime/drag.js index b5dff066672..9a16318f755 100644 --- a/v3/internal/runtime/desktop/drag.js +++ b/v3/internal/runtime/desktop/@wailsio/runtime/drag.js @@ -10,26 +10,22 @@ The electron alternative for Go /* jshint esversion: 9 */ -import {invoke} from "./invoke"; +import {invoke, IsWindows} from "./system"; import {GetFlag} from "./flags"; let shouldDrag = false; +let resizeEdge = null; +let resizable = false; +let defaultCursor = "auto"; +window._wails = window._wails || {}; +window._wails.setResizable = setResizable; +window._wails.endDrag = endDrag; export function dragTest(e) { let val = window.getComputedStyle(e.target).getPropertyValue("--webkit-app-region"); - if (val) { - val = val.trim(); - } - - if (val !== "drag") { - return false; - } - - // Only process the primary button - if (e.buttons !== 1) { + if (val && val.trim() !== "drag" || e.buttons !== 1) { return false; } - return e.detail === 1; } @@ -39,40 +35,34 @@ export function setupDrag() { window.addEventListener('mouseup', onMouseUp); } -let resizeEdge = null; -let resizable = false; - export function setResizable(value) { resizable = value; } -function testResize(e) { +export function endDrag() { + document.body.style.cursor = 'default'; + shouldDrag = false; +} + +function testResize() { if( resizeEdge ) { - invoke("resize:" + resizeEdge); + invoke(`resize:${resizeEdge}`); return true } return false; } function onMouseDown(e) { - - // Check for resizing on Windows - if( WINDOWS ) { - if (testResize()) { - return; - } - } - if (dragTest(e)) { - // Ignore drag on scrollbars - if (e.offsetX > e.target.clientWidth || e.offsetY > e.target.clientHeight) { - return; - } - shouldDrag = true; - } else { - shouldDrag = false; + if(IsWindows() && testResize() || dragTest(e)) { + shouldDrag = !!isValidDrag(e); } } +function isValidDrag(e) { + // Ignore drag on scrollbars + return !(e.offsetX > e.target.clientWidth || e.offsetY > e.target.clientHeight); +} + function onMouseUp(e) { let mousePressed = e.buttons !== undefined ? e.buttons : e.which; if (mousePressed > 0) { @@ -80,35 +70,27 @@ function onMouseUp(e) { } } -export function endDrag() { - document.body.style.cursor = 'default'; - shouldDrag = false; -} - -function setResize(cursor) { - document.documentElement.style.cursor = cursor || defaultCursor; +function setResize(cursor = defaultCursor) { + document.documentElement.style.cursor = cursor; resizeEdge = cursor; } function onMouseMove(e) { - if (shouldDrag) { - shouldDrag = false; - let mousePressed = e.buttons !== undefined ? e.buttons : e.which; - if (mousePressed > 0) { - invoke("drag"); - } - return; + shouldDrag = checkDrag(e); + if (IsWindows() && resizable) { + handleResize(e); } +} - if (WINDOWS) { - if (resizable) { - handleResize(e); - } +function checkDrag(e) { + let mousePressed = e.buttons !== undefined ? e.buttons : e.which; + if(shouldDrag && mousePressed > 0) { + invoke("drag"); + return false; } + return shouldDrag; } -let defaultCursor = "auto"; - function handleResize(e) { let resizeHandleHeight = GetFlag("system.resizeHandleHeight") || 5; let resizeHandleWidth = GetFlag("system.resizeHandleWidth") || 5; diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/events.js b/v3/internal/runtime/desktop/@wailsio/runtime/events.js new file mode 100644 index 00000000000..f76d2347949 --- /dev/null +++ b/v3/internal/runtime/desktop/@wailsio/runtime/events.js @@ -0,0 +1,134 @@ +/* + _ __ _ __ +| | / /___ _(_) /____ +| | /| / / __ `/ / / ___/ +| |/ |/ / /_/ / / (__ ) +|__/|__/\__,_/_/_/____/ +The electron alternative for Go +(c) Lea Anthony 2019-present +*/ + +/* jshint esversion: 9 */ + +/** + * @typedef {import("./types").WailsEvent} WailsEvent + */ +import {newRuntimeCallerWithID, objectNames} from "./runtime"; + +const call = newRuntimeCallerWithID(objectNames.Events, ''); +const EmitMethod = 0; +const eventListeners = new Map(); + +class Listener { + constructor(eventName, callback, maxCallbacks) { + this.eventName = eventName; + this.maxCallbacks = maxCallbacks || -1; + this.Callback = (data) => { + callback(data); + if (this.maxCallbacks === -1) return false; + this.maxCallbacks -= 1; + return this.maxCallbacks === 0; + }; + } +} + +export class WailsEvent { + constructor(name, data = null) { + this.name = name; + this.data = data; + } +} + + +window._wails = window._wails || {}; +window._wails.dispatchWailsEvent = dispatchWailsEvent; + +export function dispatchWailsEvent(event) { + let listeners = eventListeners.get(event.name); + if (listeners) { + let toRemove = listeners.filter(listener => { + let remove = listener.Callback(event); + if (remove) return true; + }); + if (toRemove.length > 0) { + listeners = listeners.filter(l => !toRemove.includes(l)); + if (listeners.length === 0) eventListeners.delete(event.name); + else eventListeners.set(event.name, listeners); + } + } +} + +/** + * Register a callback function to be called multiple times for a specific event. + * + * @param {string} eventName - The name of the event to register the callback for. + * @param {function} callback - The callback function to be called when the event is triggered. + * @param {number} maxCallbacks - The maximum number of times the callback can be called for the event. Once the maximum number is reached, the callback will no longer be called. + * + @return {function} - A function that, when called, will unregister the callback from the event. + */ +export function OnMultiple(eventName, callback, maxCallbacks) { + let listeners = eventListeners.get(eventName) || []; + const thisListener = new Listener(eventName, callback, maxCallbacks); + listeners.push(thisListener); + eventListeners.set(eventName, listeners); + return () => listenerOff(thisListener); +} + +/** + * Registers a callback function to be executed when the specified event occurs. + * + * @param {string} eventName - The name of the event. + * @param {function} callback - The callback function to be executed. It takes no parameters. + * @return {function} - A function that, when called, will unregister the callback from the event. */ +export function On(eventName, callback) { return OnMultiple(eventName, callback, -1); } + +/** + * Registers a callback function to be executed only once for the specified event. + * + * @param {string} eventName - The name of the event. + * @param {function} callback - The function to be executed when the event occurs. + * @return {void@return {function} - A function that, when called, will unregister the callback from the event. + */ +export function Once(eventName, callback) { return OnMultiple(eventName, callback, 1); } + +/** + * Removes the specified listener from the event listeners collection. + * If all listeners for the event are removed, the event key is deleted from the collection. + * + * @param {Object} listener - The listener to be removed. + */ +function listenerOff(listener) { + const eventName = listener.eventName; + let listeners = eventListeners.get(eventName).filter(l => l !== listener); + if (listeners.length === 0) eventListeners.delete(eventName); + else eventListeners.set(eventName, listeners); +} + + +/** + * Removes event listeners for the specified event names. + * + * @param {string} eventName - The name of the event to remove listeners for. + * @param {...string} additionalEventNames - Additional event names to remove listeners for. + * @return {undefined} + */ +export function Off(eventName, ...additionalEventNames) { + let eventsToRemove = [eventName, ...additionalEventNames]; + eventsToRemove.forEach(eventName => eventListeners.delete(eventName)); +} +/** + * Removes all event listeners. + * + * @function OffAll + * @returns {void} + */ +export function OffAll() { eventListeners.clear(); } + +/** + * Emits an event using the given event name. + * + * @param {WailsEvent} event - The name of the event to emit. + * @returns {any} - The result of the emitted event. + */ +export function Emit(event) { return call(EmitMethod, event); } diff --git a/v3/internal/runtime/desktop/events.test.js b/v3/internal/runtime/desktop/@wailsio/runtime/events.test.js similarity index 99% rename from v3/internal/runtime/desktop/events.test.js rename to v3/internal/runtime/desktop/@wailsio/runtime/events.test.js index a9b67965718..ed11c33ed40 100644 --- a/v3/internal/runtime/desktop/events.test.js +++ b/v3/internal/runtime/desktop/@wailsio/runtime/events.test.js @@ -1,4 +1,6 @@ + import { On, Off, OffAll, OnMultiple, WailsEvent, dispatchWailsEvent, eventListeners, Once } from './events'; + import { expect, describe, it, vi, afterEach, beforeEach } from 'vitest'; afterEach(() => { diff --git a/v3/internal/runtime/desktop/flags.js b/v3/internal/runtime/desktop/@wailsio/runtime/flags.js similarity index 84% rename from v3/internal/runtime/desktop/flags.js rename to v3/internal/runtime/desktop/@wailsio/runtime/flags.js index 4157115d3fa..153373f534a 100644 --- a/v3/internal/runtime/desktop/flags.js +++ b/v3/internal/runtime/desktop/@wailsio/runtime/flags.js @@ -52,6 +52,12 @@ function getValueFromMap(keyString) { return value; } +/** + * Retrieves the value associated with the specified key from the flag map. + * + * @param {string} keyString - The key to retrieve the value for. + * @return {*} - The value associated with the specified key. + */ export function GetFlag(keyString) { return getValueFromMap(keyString); } diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/index.js b/v3/internal/runtime/desktop/@wailsio/runtime/index.js new file mode 100644 index 00000000000..f2f9825a73e --- /dev/null +++ b/v3/internal/runtime/desktop/@wailsio/runtime/index.js @@ -0,0 +1,56 @@ +/* + _ __ _ __ +| | / /___ _(_) /____ +| | /| / / __ `/ / / ___/ +| |/ |/ / /_/ / / (__ ) +|__/|__/\__,_/_/_/____/ +The electron alternative for Go +(c) Lea Anthony 2019-present +*/ + +import {setupContextMenus} from "./contextmenu"; +import {setupDrag} from "./drag"; +import {reloadWML} from "./wml"; +import {Emit, Off, OffAll, On, Once, OnMultiple, WailsEvent} from './events'; +import {ByID, ByName, Plugin} from "./calls"; +import {Error, Info, OpenFile, Question, SaveFile, Warning} from "./dialogs"; + +export * as Application from "./application"; +export * as Browser from "./browser"; +export * as Clipboard from "./clipboard"; +export * as ContextMenu from "./contextmenu"; +export * as Flags from "./flags"; +export * as Runtime from "./runtime"; +export * as Screens from "./screens"; +export * as System from "./system"; +export * as Window from "./window"; + +export const Events = { + On, + Off, + OnMultiple, + WailsEvent, + OffAll, + Emit, + Once + +} + +export const Call = { + Plugin, + ByID, + ByName +} + +export const Dialogs = { + Info, + Error, + OpenFile, Question, Warning, SaveFile +} + +setupContextMenus(); +setupDrag(); + +document.addEventListener("DOMContentLoaded", function () { + reloadWML(); +}); diff --git a/v3/internal/runtime/desktop/api/package.json b/v3/internal/runtime/desktop/@wailsio/runtime/package.json similarity index 82% rename from v3/internal/runtime/desktop/api/package.json rename to v3/internal/runtime/desktop/@wailsio/runtime/package.json index 7335f6b13e0..85b60557cdd 100644 --- a/v3/internal/runtime/desktop/api/package.json +++ b/v3/internal/runtime/desktop/@wailsio/runtime/package.json @@ -1,7 +1,7 @@ { - "name": "@wailsapp/api", + "name": "@wailsio/runtime", "version": "3.0.0-alpha.4", - "description": "Wails Runtime API", + "description": "Wails Runtime", "main": "index.js", "repository": { "type": "git", diff --git a/v3/internal/runtime/desktop/runtime.js b/v3/internal/runtime/desktop/@wailsio/runtime/runtime.js similarity index 81% rename from v3/internal/runtime/desktop/runtime.js rename to v3/internal/runtime/desktop/@wailsio/runtime/runtime.js index 5ebb4e8c47f..6d05d1ab965 100644 --- a/v3/internal/runtime/desktop/runtime.js +++ b/v3/internal/runtime/desktop/@wailsio/runtime/runtime.js @@ -12,6 +12,7 @@ The electron alternative for Go import { nanoid } from 'nanoid/non-secure'; const runtimeURL = window.location.origin + "/wails/runtime"; + // Object Names export const objectNames = { Call: 0, @@ -27,6 +28,33 @@ export const objectNames = { } export let clientId = nanoid(); +/** + * Creates a runtime caller function that invokes a specified method on a given object within a specified window context. + * + * @param {Object} object - The object on which the method is to be invoked. + * @param {string} windowName - The name of the window context in which the method should be called. + * @returns {Function} A runtime caller function that takes the method name and optionally arguments and invokes the method within the specified window context. + */ +export function newRuntimeCaller(object, windowName) { + return function (method, args=null) { + return runtimeCall(object + "." + method, windowName, args); + }; +} + +/** + * Creates a new runtime caller with specified ID. + * + * @param {object} object - The object to invoke the method on. + * @param {string} windowName - The name of the window. + * @return {Function} - The new runtime caller function. + */ +export function newRuntimeCallerWithID(object, windowName) { + return function (method, args=null) { + return runtimeCallWithID(object, method, windowName, args); + }; +} + + function runtimeCall(method, windowName, args) { let url = new URL(runtimeURL); if( method ) { @@ -61,12 +89,6 @@ function runtimeCall(method, windowName, args) { }); } -export function newRuntimeCaller(object, windowName) { - return function (method, args=null) { - return runtimeCall(object + "." + method, windowName, args); - }; -} - function runtimeCallWithID(objectID, method, windowName, args) { let url = new URL(runtimeURL); url.searchParams.append("object", objectID); @@ -98,9 +120,3 @@ function runtimeCallWithID(objectID, method, windowName, args) { .catch(error => reject(error)); }); } - -export function newRuntimeCallerWithID(object, windowName) { - return function (method, args=null) { - return runtimeCallWithID(object, method, windowName, args); - }; -} diff --git a/v3/internal/runtime/desktop/screens.js b/v3/internal/runtime/desktop/@wailsio/runtime/screens.js similarity index 53% rename from v3/internal/runtime/desktop/screens.js rename to v3/internal/runtime/desktop/@wailsio/runtime/screens.js index 07b28a2efd2..1abcb76d503 100644 --- a/v3/internal/runtime/desktop/screens.js +++ b/v3/internal/runtime/desktop/@wailsio/runtime/screens.js @@ -15,34 +15,31 @@ The electron alternative for Go */ import {newRuntimeCallerWithID, objectNames} from "./runtime"; +const call = newRuntimeCallerWithID(objectNames.Screens, ''); -let call = newRuntimeCallerWithID(objectNames.Screens); - -let ScreensGetAll = 0; -let ScreensGetPrimary = 1; -let ScreensGetCurrent = 2; +const getAll = 0; +const getPrimary = 1; +const getCurrent = 2; /** * Gets all screens. - * @returns {Promise} + * @returns {Promise} A promise that resolves to an array of Screen objects. */ export function GetAll() { - return call(ScreensGetAll); + return call(getAll); } - /** * Gets the primary screen. - * @returns {Promise} + * @returns {Promise} A promise that resolves to the primary screen. */ export function GetPrimary() { - return call(ScreensGetPrimary); + return call(getPrimary); } - /** * Gets the current active screen. - * @returns {Promise} - * @constructor + * + * @returns {Promise} A promise that resolves with the current active screen. */ export function GetCurrent() { - return call(ScreensGetCurrent); + return call(getCurrent); } \ No newline at end of file diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/system.js b/v3/internal/runtime/desktop/@wailsio/runtime/system.js new file mode 100644 index 00000000000..73fd5281b1a --- /dev/null +++ b/v3/internal/runtime/desktop/@wailsio/runtime/system.js @@ -0,0 +1,118 @@ +/* + _ __ _ __ +| | / /___ _(_) /____ +| | /| / / __ `/ / / ___/ +| |/ |/ / /_/ / / (__ ) +|__/|__/\__,_/_/_/____/ +The electron alternative for Go +(c) Lea Anthony 2019-present +*/ + +/* jshint esversion: 9 */ + +import {newRuntimeCallerWithID, objectNames} from "./runtime"; +let call = newRuntimeCallerWithID(objectNames.System, ''); +const systemIsDarkMode = 0; +const environment = 1; + +/** + * @function + * Retrieves the system dark mode status. + * @returns {Promise} - A promise that resolves to a boolean value indicating if the system is in dark mode. + */ +export function IsDarkMode() { + return call(systemIsDarkMode); +} + + +/** + * Fetches the capabilities of the application from the server. + * + * @async + * @function Capabilities + * @returns {Promise} A promise that resolves to an object containing the capabilities. + */ +export async function Capabilities() { + let response = fetch("/wails/capabilities"); + return response.json(); +} + +/** + * @typedef {object} EnvironmentInfo + * @property {string} OS - The operating system in use. + * @property {string} Arch - The architecture of the system. + */ + +/** + * @function + * Retrieves environment details. + * @returns {Promise} - A promise that resolves to an object containing OS and system architecture. + */ +export function Environment() { + return call(environment); +} + +export let invoke = null; +let environmentCache = null; + +Environment() + .then(result => { + environmentCache = result; + invoke = IsWindows() ? window.chrome.webview.postMessage : window.webkit.messageHandlers.external.postMessage; + }) + .catch(error => { + console.error(`Error getting Environment: ${error}`); + }); + +/** + * Checks if the current operating system is Windows. + * + * @return {boolean} True if the operating system is Windows, otherwise false. + */ +export function IsWindows() { + return environmentCache.OS === "windows"; +} + +/** + * Checks if the current operating system is Linux. + * + * @returns {boolean} Returns true if the current operating system is Linux, false otherwise. + */ +export function IsLinux() { + return environmentCache.OS === "linux"; +} + +/** + * Checks if the current environment is a macOS operating system. + * + * @returns {boolean} True if the environment is macOS, false otherwise. + */ +export function IsMac() { + return environmentCache.OS === "darwin"; +} + +/** + * Checks if the current environment architecture is AMD64. + * @returns {boolean} True if the current environment architecture is AMD64, false otherwise. + */ +export function IsAMD64() { + return environmentCache.Arch === "amd64"; +} + +/** + * Checks if the current architecture is ARM. + * + * @returns {boolean} True if the current architecture is ARM, false otherwise. + */ +export function IsARM() { + return environmentCache.Arch === "arm"; +} + +/** + * Checks if the current environment is ARM64 architecture. + * + * @returns {boolean} - Returns true if the environment is ARM64 architecture, otherwise returns false. + */ +export function IsARM64() { + return environmentCache.Arch === "arm64"; +} diff --git a/v3/internal/runtime/desktop/api/types.d.ts b/v3/internal/runtime/desktop/@wailsio/runtime/types.d.ts similarity index 100% rename from v3/internal/runtime/desktop/api/types.d.ts rename to v3/internal/runtime/desktop/@wailsio/runtime/types.d.ts diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/window.js b/v3/internal/runtime/desktop/@wailsio/runtime/window.js new file mode 100644 index 00000000000..e125c057d95 --- /dev/null +++ b/v3/internal/runtime/desktop/@wailsio/runtime/window.js @@ -0,0 +1,122 @@ +/* + _ __ _ __ +| | / /___ _(_) /____ +| | /| / / __ `/ / / ___/ +| |/ |/ / /_/ / / (__ ) +|__/|__/\__,_/_/_/____/ +The electron alternative for Go +(c) Lea Anthony 2019-present +*/ + +/* jshint esversion: 9 */ + +/** + * @typedef {import("../api/types").Size} Size + * @typedef {import("../api/types").Position} Position + * @typedef {import("../api/types").Screen} Screen + */ + +import {newRuntimeCallerWithID, objectNames} from "./runtime"; + +const center = 0; +const setTitle = 1; +const fullscreen = 2; +const unFullscreen = 3; +const setSize = 4; +const size = 5; +const setMaxSize = 6; +const setMinSize = 7; +const setAlwaysOnTop = 8; +const setRelativePosition = 9; +const relativePosition = 10; +const screen = 11; +const hide = 12; +const maximise = 13; +const unMaximise = 14; +const toggleMaximise = 15; +const minimise = 16; +const unMinimise = 17; +const restore = 18; +const show = 19; +const close = 20; +const setBackgroundColour = 21; +const setResizable = 22; +const width = 23; +const height = 24; +const zoomIn = 25; +const zoomOut = 26; +const zoomReset = 27; +const getZoomLevel = 28; +const setZoomLevel = 29; + +const thisWindow = newRuntimeCallerWithID(objectNames.Window, ''); + +function createWindow(call) { + return { + Get: (windowName) => createWindow(newRuntimeCallerWithID(objectNames.Window, windowName)), + Center: () => call(center), + SetTitle: (title) => call(setTitle, {title}), + Fullscreen: () => call(fullscreen), + UnFullscreen: () => call(unFullscreen), + SetSize: (width, height) => call(setSize, {width, height}), + Size: () => call(size), + SetMaxSize: (width, height) => call(setMaxSize, {width, height}), + SetMinSize: (width, height) => call(setMinSize, {width, height}), + SetAlwaysOnTop: (onTop) => call(setAlwaysOnTop, {alwaysOnTop: onTop}), + SetRelativePosition: (x, y) => call(setRelativePosition, {x, y}), + RelativePosition: () => call(relativePosition), + Screen: () => call(screen), + Hide: () => call(hide), + Maximise: () => call(maximise), + UnMaximise: () => call(unMaximise), + ToggleMaximise: () => call(toggleMaximise), + Minimise: () => call(minimise), + UnMinimise: () => call(unMinimise), + Restore: () => call(restore), + Show: () => call(show), + Close: () => call(close), + SetBackgroundColour: (r, g, b, a) => call(setBackgroundColour, {r, g, b, a}), + SetResizable: (resizable) => call(setResizable, {resizable}), + Width: () => call(width), + Height: () => call(height), + ZoomIn: () => call(zoomIn), + ZoomOut: () => call(zoomOut), + ZoomReset: () => call(zoomReset), + GetZoomLevel: () => call(getZoomLevel), + SetZoomLevel: (zoomLevel) => call(setZoomLevel, {zoomLevel}), + }; +} + +/** + * Gets the specified window. + * + * @param {string} windowName - The name of the window to get. + * @return {Object} - The specified window object. + */ +export function Get(windowName) { + return createWindow(newRuntimeCallerWithID(objectNames.Window, windowName)); +} + +/** + * Returns a map of all methods in the current window. + * @returns {Map} - A map of window methods. + */ +export function WindowMethods(targetWindow) { + // Create a new map to store methods + let result = new Map(); + + // Iterate over all properties of the window object + for (let method in targetWindow) { + // Check if the property is indeed a method (function) + if(typeof targetWindow[method] === 'function') { + // Add the method to the map + result.set(method, targetWindow[method]); + } + + } + // Return the map of window methods + return result; +} +export default { + ...Get('') +} diff --git a/v3/internal/runtime/desktop/wml.js b/v3/internal/runtime/desktop/@wailsio/runtime/wml.js similarity index 70% rename from v3/internal/runtime/desktop/wml.js rename to v3/internal/runtime/desktop/@wailsio/runtime/wml.js index 32b7bc36f0a..c8c2e715d03 100644 --- a/v3/internal/runtime/desktop/wml.js +++ b/v3/internal/runtime/desktop/@wailsio/runtime/wml.js @@ -1,12 +1,26 @@ import {Emit, WailsEvent} from "./events"; import {Question} from "./dialogs"; - +import {WindowMethods, Get} from "./window"; + +/** + * Sends an event with the given name and optional data. + * + * @param {string} eventName - The name of the event to send. + * @param {any} [data=null] - Optional data to send along with the event. + * + * @return {void} + */ function sendEvent(eventName, data=null) { let event = new WailsEvent(eventName, data); Emit(event); } +/** + * Adds event listeners to elements with `wml-event` attribute. + * + * @return {void} + */ function addWMLEventListeners() { const elements = document.querySelectorAll('[wml-event]'); elements.forEach(function (element) { @@ -25,8 +39,8 @@ function addWMLEventListeners() { } sendEvent(eventType); }; - // Remove existing listeners + // Remove existing listeners element.removeEventListener(trigger, callback); // Add new listener @@ -34,13 +48,30 @@ function addWMLEventListeners() { }); } +/** + * Calls a method on the window object. + * + * @param {string} method - The name of the method to call on the window object. + * + * @return {void} + */ function callWindowMethod(method) { - if (wails.Window[method] === undefined) { + // TODO: Make this a parameter! + let windowName = ''; + let targetWindow = Get(''); + let methodMap = WindowMethods(targetWindow); + if (!methodMap.has(method)) { console.log("Window method " + method + " not found"); } - wails.Window[method](); + methodMap.get(method)(); } +/** + * Adds window listeners for elements with the 'wml-window' attribute. + * Removes any existing listeners before adding new ones. + * + * @return {void} + */ function addWMLWindowListeners() { const elements = document.querySelectorAll('[wml-window]'); elements.forEach(function (element) { @@ -68,6 +99,15 @@ function addWMLWindowListeners() { }); } +/** + * Adds a listener to elements with the 'wml-openurl' attribute. + * When the specified trigger event is fired on any of these elements, + * the listener will open the URL specified by the 'wml-openurl' attribute. + * If a 'wml-confirm' attribute is provided, a confirmation dialog will be displayed, + * and the URL will only be opened if the user confirms. + * + * @return {void} + */ function addWMLOpenBrowserListener() { const elements = document.querySelectorAll('[wml-openurl]'); elements.forEach(function (element) { @@ -95,7 +135,13 @@ function addWMLOpenBrowserListener() { }); } +/** + * Reloads the WML page by adding necessary event listeners and browser listeners. + * + * @return {void} + */ export function reloadWML() { + console.log("Reloading WML"); addWMLEventListeners(); addWMLWindowListeners(); addWMLOpenBrowserListener(); diff --git a/v3/internal/runtime/desktop/README.md b/v3/internal/runtime/desktop/README.md index 78ef387e4b7..3da6938c409 100644 --- a/v3/internal/runtime/desktop/README.md +++ b/v3/internal/runtime/desktop/README.md @@ -1,3 +1,8 @@ # README -After updating any files in this directory, you must run `wails task build:runtime` to regenerate the compiled JS. \ No newline at end of file +The `main.js` file in this directory is the entrypoint for the `runtime.js` file that may be +loaded at runtime. This will add `window.wails` and `window._wails` to the global scope. + +NOTE: It is preferable to use the `@wailsio/runtime` package to use the runtime. + +After updating any files in this directory, you must run `wails3 task build:runtime` to regenerate the compiled JS. \ No newline at end of file diff --git a/v3/internal/runtime/desktop/api/README.md b/v3/internal/runtime/desktop/api/README.md deleted file mode 100644 index 0cb344e83a0..00000000000 --- a/v3/internal/runtime/desktop/api/README.md +++ /dev/null @@ -1,363 +0,0 @@ -# Wails API - -This package provides a typed Javascript API for Wails applications. - -It provides methods for the following components: - -- [Dialog](#dialog) -- [Events](#events) -- [Window](#window) -- [Plugin](#plugin) -- [Screens](#screens) -- [Application](#application) - -## Installation - -In your Wails application, run the following command in the frontend project directory: - -```bash -npm install -D @wailsapp/api -``` - -## Usage - -Import the API into your application: - -```javascript -import * as Wails from "@wailsapp/api"; -``` - -Then use the API components: - -```javascript -function showDialog() { - Wails.Dialog.Info({ - Title: "Hello", - }).then((result) => { - console.log("Result: " + result); - }); -} -``` - -Individual components of the API can also be imported directly. - - - -## API - -### Dialog - -The Dialog API provides access to the native system dialogs. - -```javascript -import { Dialog } from "@wailsapp/api"; - -function example() { - Dialog.Info({ - Title: "Hello", - }).then((result) => { - console.log("Result: " + result); - }); -} -``` - -#### Message Dialogs - -Message dialogs are used to display a message to the user. -They can be used to display information, errors, warnings and questions. -Each method returns the button that was pressed by the user. - -- `Info(options: MessageDialogOptions): Promise` -- `Error(options: MessageDialogOptions): Promise` -- `Warning(options: MessageDialogOptions): Promise` -- `Question(options: MessageDialogOptions): Promise` - -#### Open Dialog - -The Open Dialog is used to open a file or directory. It returns the path of the selected file or directory. -If the `AllowsMultipleFiles` option is set, multiple files or directories can be selected and are returned -as an array of file paths. - -- `Open(options: OpenDialogOptions): Promise` - -#### Save Dialog - -The Save Dialog is used to save a file. It returns the path of the selected file. - -- `Save(options: SaveDialogOptions): Promise` - -### Events - -The Events API provides access to the Wails event system. This is a global event system -that can be used to send events between the Go and Javascript. -Events are available to every window in a multi-window application. -These API methods are specific to the window in which they are called in. - -```javascript -import { Events } from "@wailsapp/api"; - -function example() { - // Emit an event - Events.Emit("myevent", { message: "Hello" }); - - // Subscribe to an event - let unsub = Events.On("otherEvent", (data) => { - console.log("Received event: " + data); - }); - - // Unsubscribe from the event - unsub(); -} -``` - -#### Emit - -Emit an event with optional data. - -- `Emit(eventName: string, data?: any): void` - -#### Subscribe - -Three methods are provided to subscribe to an event: - - `On(eventName: string, callback: (data: any) => void): () => void` - Subscribe to all events of the given name - - `Once(eventName: string, callback: (data: any) => void): () => void` - Subscribe to one event of the given name - - `OnMultiple(eventName: string, callback: (data: any) => void, count: number): () => void` - Subscribe to multiple events of the given name - -The callback will be called when the event is emitted. -The returned function can be called to unsubscribe from the event. - -#### Unsubscribe - -As well as unsubscribing from a single event, you can unsubscribe from events of a given name or all events. - - `Off(eventName: string, additionalEventNames: ...string): void` - Unsubscribe from all events of the given name(s) - - `OffAll(): void` - Unsubscribe all events - -### Window - -The Window API provides a number of methods that interact with the window in which the API is called. - -- `Center: (void) => void` - Center the window -- `SetTitle: (title) => void` - Set the window title -- `Fullscreen: () => void` - Set the window to fullscreen -- `UnFullscreen: () => void` - Restore a fullscreen window -- `SetSize: (width: number, height: number) => void` - Set the window size -- `Size: () => Size` - Get the window size -- `SetMaxSize: (width, height) => void` - Set the window maximum size -- `SetMinSize: (width, height) => void` - Set the window minimum size -- `SetAlwaysOnTop: (onTop) => void` - Set window to be always on top -- `SetPosition: (x, y) => void` - Set the window position -- `Position: () => Position` - Get the window position -- `SetResizable: (resizable) => void` - Set whether the window is resizable -- `Screen: () => Screen` - Get information about the screen the window is on -- `Hide: () => void` - Hide the window -- `Show: () => void` - Show the window -- `Maximise: () => void` - Maximise the window -- `Close: () => void` - Close the window -- `ToggleMaximise: () => void` - Toggle the window maximise state -- `UnMaximise: () => void` - UnMaximise the window -- `Minimise: () => void` - Minimise the window -- `UnMinimise: () => void` - UnMinimise the window -- `SetBackgroundColour: (r, g, b, a) => void` - Set the background colour of the window - -### Plugin - -The Plugin API provides access to the Wails plugin system. -This method provides the ability to call a plugin method from the frontend. - -```javascript - -import { Plugin } from "@wailsapp/api"; - -function example() { - // Call a plugin method - Plugin.Call("myplugin", "MyMethod", { message: "Hello" }).then((result) => { - console.log("Result: " + result); - }); -} -``` - -### Screens - -The Screens API provides access to the Wails screen system. - -```javascript -import { Screens } from "@wailsapp/api"; - -function example() { - // Get all attatched screens - Screens.GetAll().then((screens) => { - console.log("Screens: " + screens); - }); - - // Get the primary screen - Screens.GetPrimary().then((screen) => { - console.log("Primary screen: " + screen); - }); - - // Get the screen the window is on - Screens.GetCurrent().then((screen) => { - console.log("Window screen: " + screen); - }); -} -``` - -- `GetAll: () => Promise` - Get all screens -- `GetPrimary: () => Promise` - Get the primary screen -- `GetCurrent: () => Promise` - Get the screen the window is on - -### Application - -The Application API provides access to the Wails application system. - -```javascript -import { Application } from "@wailsapp/api"; - -function example() { - - // Hide the application - Application.Hide(); - - // Shopw the application - Application.Show(); - - // Quit the application - Application.Quit(); - -} -``` - -- `Hide: () => void` - Hide the application -- `Show: () => void` - Show the application -- `Quit: () => void` - Quit the application - -## Types - -This is a comprehensive list of types used by the Wails API. - -```typescript - -export interface Button { - // The label of the button - Label?: string; - // True if this button is the cancel button (selected when pressing escape) - IsCancel?: boolean; - // True if this button is the default button (selected when pressing enter) - IsDefault?: boolean; -} - -interface MessageDialogOptions { - // The title for the dialog - Title?: string; - // The message to display - Message?: string; - // The buttons to use on the dialog - Buttons?: Button[]; -} - -export interface OpenFileDialogOptions { - // Allows the user to be able to select directories - CanChooseDirectories?: boolean; - // Allows the user to be able to select files - CanChooseFiles?: boolean; - // Provide an option to create directories in the dialog - CanCreateDirectories?: boolean; - // Makes the dialog show hidden files - ShowHiddenFiles?: boolean; - // Whether the dialog should follow filesystem aliases - ResolvesAliases?: boolean; - // Allow the user to select multiple files or directories - AllowsMultipleSelection?: boolean; - // Hide the extension when showing the filename - HideExtension?: boolean; - // Allow the user to select files where the system hides their extensions - CanSelectHiddenExtension?: boolean; - // Treats file packages as directories, e.g. .app on macOS - TreatsFilePackagesAsDirectories?: boolean; - // Allows selection of filetypes not specified in the filters - AllowsOtherFiletypes?: boolean; - // The file filters to use in the dialog - Filters?: FileFilter[]; - // The title of the dialog - Title?: string; - // The message to display - Message?: string; - // The label for the select button - ButtonText?: string; - // The default directory to open the dialog in - Directory?: string; -} -export interface FileFilter { - // The display name for the filter, e.g. "Text Files" - DisplayName?: string; - // The pattern to use for the filter, e.g. "*.txt;*.md" - Pattern?: string; -} -export interface SaveFileDialogOptions { - // Provide an option to create directories in the dialog - CanCreateDirectories?: boolean; - // Makes the dialog show hidden files - ShowHiddenFiles?: boolean; - // Allow the user to select files where the system hides their extensions - CanSelectHiddenExtension?: boolean; - // Allows selection of filetypes not specified in the filters - AllowOtherFiletypes?: boolean; - // Hide the extension when showing the filename - HideExtension?: boolean; - // Treats file packages as directories, e.g. .app on macOS - TreatsFilePackagesAsDirectories?: boolean; - // The message to show in the dialog - Message?: string; - // The default directory to open the dialog in - Directory?: string; - // The default filename to use in the dialog - Filename?: string; - // The label for the select button - ButtonText?: string; -} - -export interface Screen { - // The screen ID - Id: string; - // The screen name - Name: string; - // The screen scale. 1 = standard resolution, 2: 2x retina, etc. - Scale: number; - // The X position of the screen - X: number; - // The Y position of the screen - Y: number; - // The width and height of the screen - Size: Size; - // The bounds of the screen - Bounds: Rect; - // The work area of the screen - WorkArea: Rect; - // True if this is the primary screen - IsPrimary: boolean; - // The rotation of the screen - Rotation: number; -} -export interface Rect { - X: number; - Y: number; - Width: number; - Height: number; -} - -export interface WailsEvent { - // The name of the event - Name: string; - // The data associated with the event - Data?: any; -} - -export interface Size { - Width: number; - Height: number; -} -export interface Position { - X: number; - Y: number; -} - -``` \ No newline at end of file diff --git a/v3/internal/runtime/desktop/api/application.js b/v3/internal/runtime/desktop/api/application.js deleted file mode 100644 index 9ae7ba915f8..00000000000 --- a/v3/internal/runtime/desktop/api/application.js +++ /dev/null @@ -1,35 +0,0 @@ -/* - _ __ _ __ -| | / /___ _(_) /____ -| | /| / / __ `/ / / ___/ -| |/ |/ / /_/ / / (__ ) -|__/|__/\__,_/_/_/____/ -The electron alternative for Go -(c) Lea Anthony 2019-present -*/ - -/* jshint esversion: 9 */ - -/** - * The Application API provides methods to interact with the application. - */ -export const Application = { - /** - * Hides the application - */ - Hide: () => { - return wails.Application.Hide(); - }, - /** - * Shows the application - */ - Show: () => { - return wails.Application.Show(); - }, - /** - * Quits the application - */ - Quit: () => { - return wails.Application.Quit(); - }, -}; diff --git a/v3/internal/runtime/desktop/api/browser.js b/v3/internal/runtime/desktop/api/browser.js deleted file mode 100644 index 3807ad640b6..00000000000 --- a/v3/internal/runtime/desktop/api/browser.js +++ /dev/null @@ -1,24 +0,0 @@ -/* - _ __ _ __ -| | / /___ _(_) /____ -| | /| / / __ `/ / / ___/ -| |/ |/ / /_/ / / (__ ) -|__/|__/\__,_/_/_/____/ -The electron alternative for Go -(c) Lea Anthony 2019-present -*/ - -/* jshint esversion: 9 */ - -/** - * The Browser API provides methods to interact with the system browser. - */ -export const Browser = { - /** - * Opens a browser window to the given URL - * @returns {Promise} - */ - OpenURL: (url) => { - return wails.Browser.OpenURL(url); - }, -}; diff --git a/v3/internal/runtime/desktop/api/clipboard.js b/v3/internal/runtime/desktop/api/clipboard.js deleted file mode 100644 index c18dcbe1869..00000000000 --- a/v3/internal/runtime/desktop/api/clipboard.js +++ /dev/null @@ -1,31 +0,0 @@ -/* - _ __ _ __ -| | / /___ _(_) /____ -| | /| / / __ `/ / / ___/ -| |/ |/ / /_/ / / (__ ) -|__/|__/\__,_/_/_/____/ -The electron alternative for Go -(c) Lea Anthony 2019-present -*/ - -/* jshint esversion: 9 */ - -/** - * The Clipboard API provides methods to interact with the system clipboard. - */ -export const Clipboard = { - /** - * Gets the text from the clipboard - * @returns {Promise} - */ - Text: () => { - return wails.Clipboard.Text(); - }, - /** - * Sets the text on the clipboard - * @param {string} text - text to set in the clipboard - */ - SetText: (text) => { - return wails.Clipboard.SetText(text); - }, -}; diff --git a/v3/internal/runtime/desktop/api/dialogs.js b/v3/internal/runtime/desktop/api/dialogs.js deleted file mode 100644 index e129c31dab1..00000000000 --- a/v3/internal/runtime/desktop/api/dialogs.js +++ /dev/null @@ -1,75 +0,0 @@ -/* - _ __ _ __ -| | / /___ _(_) /____ -| | /| / / __ `/ / / ___/ -| |/ |/ / /_/ / / (__ ) -|__/|__/\__,_/_/_/____/ -The electron alternative for Go -(c) Lea Anthony 2019-present -*/ - -/* jshint esversion: 9 */ - -/** - * @typedef {import("./types").MessageDialogOptions} MessageDialogOptions - * @typedef {import("./types").OpenDialogOptions} OpenDialogOptions - * @typedef {import("./types").SaveDialogOptions} SaveDialogOptions - */ -/** - * The Dialog API provides methods to interact with system dialogs. - */ -export const Dialog = { - /** - * Shows an info dialog - * @param {MessageDialogOptions} options - options for the dialog - * @returns {Promise} - */ - Info: (options) => { - return wails.Dialog.Info(options); - }, - /** - * Shows a warning dialog - * @param {MessageDialogOptions} options - options for the dialog - * @returns {Promise} - */ - Warning: (options) => { - return wails.Dialog.Warning(options); - }, - /** - * Shows an error dialog - * @param {MessageDialogOptions} options - options for the dialog - * @returns {Promise} - */ - Error: (options) => { - return wails.Dialog.Error(options); - }, - - /** - * Shows a question dialog - * @param {MessageDialogOptions} options - options for the dialog - * @returns {Promise} - */ - Question: (options) => { - return wails.Dialog.Question(options); - }, - - /** - * Shows a file open dialog and returns the files selected by the user. - * A blank string indicates that the dialog was cancelled. - * @param {OpenDialogOptions} options - options for the dialog - * @returns {Promise|Promise} - */ - OpenFile: (options) => { - return wails.Dialog.OpenFile(options); - }, - - /** - * Shows a file save dialog and returns the filename given by the user. - * A blank string indicates that the dialog was cancelled. - * @param {SaveDialogOptions} options - options for the dialog - * @returns {Promise} - */ - SaveFile: (options) => { - return wails.Dialog.SaveFile(options); - }, -}; \ No newline at end of file diff --git a/v3/internal/runtime/desktop/api/event_types.js b/v3/internal/runtime/desktop/api/event_types.js deleted file mode 100644 index 6ba09269b1b..00000000000 --- a/v3/internal/runtime/desktop/api/event_types.js +++ /dev/null @@ -1,178 +0,0 @@ - -export const EventTypes = { - Windows: { - SystemThemeChanged: "windows:SystemThemeChanged", - APMPowerStatusChange: "windows:APMPowerStatusChange", - APMSuspend: "windows:APMSuspend", - APMResumeAutomatic: "windows:APMResumeAutomatic", - APMResumeSuspend: "windows:APMResumeSuspend", - APMPowerSettingChange: "windows:APMPowerSettingChange", - ApplicationStarted: "windows:ApplicationStarted", - WebViewNavigationCompleted: "windows:WebViewNavigationCompleted", - WindowInactive: "windows:WindowInactive", - WindowActive: "windows:WindowActive", - WindowClickActive: "windows:WindowClickActive", - WindowMaximise: "windows:WindowMaximise", - WindowUnMaximise: "windows:WindowUnMaximise", - WindowFullscreen: "windows:WindowFullscreen", - WindowUnFullscreen: "windows:WindowUnFullscreen", - WindowRestore: "windows:WindowRestore", - WindowMinimise: "windows:WindowMinimise", - WindowUnMinimise: "windows:WindowUnMinimise", - WindowClose: "windows:WindowClose", - WindowSetFocus: "windows:WindowSetFocus", - WindowKillFocus: "windows:WindowKillFocus", - WindowDragDrop: "windows:WindowDragDrop", - WindowDragEnter: "windows:WindowDragEnter", - WindowDragLeave: "windows:WindowDragLeave", - WindowDragOver: "windows:WindowDragOver", - }, - Mac: { - ApplicationDidBecomeActive: "mac:ApplicationDidBecomeActive", - ApplicationDidChangeBackingProperties: "mac:ApplicationDidChangeBackingProperties", - ApplicationDidChangeEffectiveAppearance: "mac:ApplicationDidChangeEffectiveAppearance", - ApplicationDidChangeIcon: "mac:ApplicationDidChangeIcon", - ApplicationDidChangeOcclusionState: "mac:ApplicationDidChangeOcclusionState", - ApplicationDidChangeScreenParameters: "mac:ApplicationDidChangeScreenParameters", - ApplicationDidChangeStatusBarFrame: "mac:ApplicationDidChangeStatusBarFrame", - ApplicationDidChangeStatusBarOrientation: "mac:ApplicationDidChangeStatusBarOrientation", - ApplicationDidFinishLaunching: "mac:ApplicationDidFinishLaunching", - ApplicationDidHide: "mac:ApplicationDidHide", - ApplicationDidResignActiveNotification: "mac:ApplicationDidResignActiveNotification", - ApplicationDidUnhide: "mac:ApplicationDidUnhide", - ApplicationDidUpdate: "mac:ApplicationDidUpdate", - ApplicationWillBecomeActive: "mac:ApplicationWillBecomeActive", - ApplicationWillFinishLaunching: "mac:ApplicationWillFinishLaunching", - ApplicationWillHide: "mac:ApplicationWillHide", - ApplicationWillResignActive: "mac:ApplicationWillResignActive", - ApplicationWillTerminate: "mac:ApplicationWillTerminate", - ApplicationWillUnhide: "mac:ApplicationWillUnhide", - ApplicationWillUpdate: "mac:ApplicationWillUpdate", - ApplicationDidChangeTheme: "mac:ApplicationDidChangeTheme!", - ApplicationShouldHandleReopen: "mac:ApplicationShouldHandleReopen!", - WindowDidBecomeKey: "mac:WindowDidBecomeKey", - WindowDidBecomeMain: "mac:WindowDidBecomeMain", - WindowDidBeginSheet: "mac:WindowDidBeginSheet", - WindowDidChangeAlpha: "mac:WindowDidChangeAlpha", - WindowDidChangeBackingLocation: "mac:WindowDidChangeBackingLocation", - WindowDidChangeBackingProperties: "mac:WindowDidChangeBackingProperties", - WindowDidChangeCollectionBehavior: "mac:WindowDidChangeCollectionBehavior", - WindowDidChangeEffectiveAppearance: "mac:WindowDidChangeEffectiveAppearance", - WindowDidChangeOcclusionState: "mac:WindowDidChangeOcclusionState", - WindowDidChangeOrderingMode: "mac:WindowDidChangeOrderingMode", - WindowDidChangeScreen: "mac:WindowDidChangeScreen", - WindowDidChangeScreenParameters: "mac:WindowDidChangeScreenParameters", - WindowDidChangeScreenProfile: "mac:WindowDidChangeScreenProfile", - WindowDidChangeScreenSpace: "mac:WindowDidChangeScreenSpace", - WindowDidChangeScreenSpaceProperties: "mac:WindowDidChangeScreenSpaceProperties", - WindowDidChangeSharingType: "mac:WindowDidChangeSharingType", - WindowDidChangeSpace: "mac:WindowDidChangeSpace", - WindowDidChangeSpaceOrderingMode: "mac:WindowDidChangeSpaceOrderingMode", - WindowDidChangeTitle: "mac:WindowDidChangeTitle", - WindowDidChangeToolbar: "mac:WindowDidChangeToolbar", - WindowDidChangeVisibility: "mac:WindowDidChangeVisibility", - WindowDidDeminiaturize: "mac:WindowDidDeminiaturize", - WindowDidEndSheet: "mac:WindowDidEndSheet", - WindowDidEnterFullScreen: "mac:WindowDidEnterFullScreen", - WindowDidEnterVersionBrowser: "mac:WindowDidEnterVersionBrowser", - WindowDidExitFullScreen: "mac:WindowDidExitFullScreen", - WindowDidExitVersionBrowser: "mac:WindowDidExitVersionBrowser", - WindowDidExpose: "mac:WindowDidExpose", - WindowDidFocus: "mac:WindowDidFocus", - WindowDidMiniaturize: "mac:WindowDidMiniaturize", - WindowDidMove: "mac:WindowDidMove", - WindowDidOrderOffScreen: "mac:WindowDidOrderOffScreen", - WindowDidOrderOnScreen: "mac:WindowDidOrderOnScreen", - WindowDidResignKey: "mac:WindowDidResignKey", - WindowDidResignMain: "mac:WindowDidResignMain", - WindowDidResize: "mac:WindowDidResize", - WindowDidUpdate: "mac:WindowDidUpdate", - WindowDidUpdateAlpha: "mac:WindowDidUpdateAlpha", - WindowDidUpdateCollectionBehavior: "mac:WindowDidUpdateCollectionBehavior", - WindowDidUpdateCollectionProperties: "mac:WindowDidUpdateCollectionProperties", - WindowDidUpdateShadow: "mac:WindowDidUpdateShadow", - WindowDidUpdateTitle: "mac:WindowDidUpdateTitle", - WindowDidUpdateToolbar: "mac:WindowDidUpdateToolbar", - WindowDidUpdateVisibility: "mac:WindowDidUpdateVisibility", - WindowShouldClose: "mac:WindowShouldClose!", - WindowWillBecomeKey: "mac:WindowWillBecomeKey", - WindowWillBecomeMain: "mac:WindowWillBecomeMain", - WindowWillBeginSheet: "mac:WindowWillBeginSheet", - WindowWillChangeOrderingMode: "mac:WindowWillChangeOrderingMode", - WindowWillClose: "mac:WindowWillClose", - WindowWillDeminiaturize: "mac:WindowWillDeminiaturize", - WindowWillEnterFullScreen: "mac:WindowWillEnterFullScreen", - WindowWillEnterVersionBrowser: "mac:WindowWillEnterVersionBrowser", - WindowWillExitFullScreen: "mac:WindowWillExitFullScreen", - WindowWillExitVersionBrowser: "mac:WindowWillExitVersionBrowser", - WindowWillFocus: "mac:WindowWillFocus", - WindowWillMiniaturize: "mac:WindowWillMiniaturize", - WindowWillMove: "mac:WindowWillMove", - WindowWillOrderOffScreen: "mac:WindowWillOrderOffScreen", - WindowWillOrderOnScreen: "mac:WindowWillOrderOnScreen", - WindowWillResignMain: "mac:WindowWillResignMain", - WindowWillResize: "mac:WindowWillResize", - WindowWillUnfocus: "mac:WindowWillUnfocus", - WindowWillUpdate: "mac:WindowWillUpdate", - WindowWillUpdateAlpha: "mac:WindowWillUpdateAlpha", - WindowWillUpdateCollectionBehavior: "mac:WindowWillUpdateCollectionBehavior", - WindowWillUpdateCollectionProperties: "mac:WindowWillUpdateCollectionProperties", - WindowWillUpdateShadow: "mac:WindowWillUpdateShadow", - WindowWillUpdateTitle: "mac:WindowWillUpdateTitle", - WindowWillUpdateToolbar: "mac:WindowWillUpdateToolbar", - WindowWillUpdateVisibility: "mac:WindowWillUpdateVisibility", - WindowWillUseStandardFrame: "mac:WindowWillUseStandardFrame", - MenuWillOpen: "mac:MenuWillOpen", - MenuDidOpen: "mac:MenuDidOpen", - MenuDidClose: "mac:MenuDidClose", - MenuWillSendAction: "mac:MenuWillSendAction", - MenuDidSendAction: "mac:MenuDidSendAction", - MenuWillHighlightItem: "mac:MenuWillHighlightItem", - MenuDidHighlightItem: "mac:MenuDidHighlightItem", - MenuWillDisplayItem: "mac:MenuWillDisplayItem", - MenuDidDisplayItem: "mac:MenuDidDisplayItem", - MenuWillAddItem: "mac:MenuWillAddItem", - MenuDidAddItem: "mac:MenuDidAddItem", - MenuWillRemoveItem: "mac:MenuWillRemoveItem", - MenuDidRemoveItem: "mac:MenuDidRemoveItem", - MenuWillBeginTracking: "mac:MenuWillBeginTracking", - MenuDidBeginTracking: "mac:MenuDidBeginTracking", - MenuWillEndTracking: "mac:MenuWillEndTracking", - MenuDidEndTracking: "mac:MenuDidEndTracking", - MenuWillUpdate: "mac:MenuWillUpdate", - MenuDidUpdate: "mac:MenuDidUpdate", - MenuWillPopUp: "mac:MenuWillPopUp", - MenuDidPopUp: "mac:MenuDidPopUp", - MenuWillSendActionToItem: "mac:MenuWillSendActionToItem", - MenuDidSendActionToItem: "mac:MenuDidSendActionToItem", - WebViewDidStartProvisionalNavigation: "mac:WebViewDidStartProvisionalNavigation", - WebViewDidReceiveServerRedirectForProvisionalNavigation: "mac:WebViewDidReceiveServerRedirectForProvisionalNavigation", - WebViewDidFinishNavigation: "mac:WebViewDidFinishNavigation", - WebViewDidCommitNavigation: "mac:WebViewDidCommitNavigation", - WindowFileDraggingEntered: "mac:WindowFileDraggingEntered", - WindowFileDraggingPerformed: "mac:WindowFileDraggingPerformed", - WindowFileDraggingExited: "mac:WindowFileDraggingExited", - }, - Common: { - ApplicationStarted: "common:ApplicationStarted", - WindowMaximise: "common:WindowMaximise", - WindowUnMaximise: "common:WindowUnMaximise", - WindowFullscreen: "common:WindowFullscreen", - WindowUnFullscreen: "common:WindowUnFullscreen", - WindowRestore: "common:WindowRestore", - WindowMinimise: "common:WindowMinimise", - WindowUnMinimise: "common:WindowUnMinimise", - WindowClosing: "common:WindowClosing", - WindowZoom: "common:WindowZoom", - WindowZoomIn: "common:WindowZoomIn", - WindowZoomOut: "common:WindowZoomOut", - WindowZoomReset: "common:WindowZoomReset", - WindowFocus: "common:WindowFocus", - WindowLostFocus: "common:WindowLostFocus", - WindowShow: "common:WindowShow", - WindowHide: "common:WindowHide", - WindowDPIChanged: "common:WindowDPIChanged", - WindowFilesDropped: "common:WindowFilesDropped", - ThemeChanged: "common:ThemeChanged", - }, -}; diff --git a/v3/internal/runtime/desktop/api/events.js b/v3/internal/runtime/desktop/api/events.js deleted file mode 100644 index 208177978c9..00000000000 --- a/v3/internal/runtime/desktop/api/events.js +++ /dev/null @@ -1,74 +0,0 @@ -/* - _ __ _ __ -| | / /___ _(_) /____ -| | /| / / __ `/ / / ___/ -| |/ |/ / /_/ / / (__ ) -|__/|__/\__,_/_/_/____/ -The electron alternative for Go -(c) Lea Anthony 2019-present -*/ - -/* jshint esversion: 9 */ - -import {EventTypes} from './event_types'; - -/** - * The Events API provides methods to interact with the event system. - */ -export const Events = { - /** - * Emit an event - * @param {string} name - * @param {any=} data - */ - Emit: (name, data) => { - return wails.Events.Emit(name, data); - }, - /** - * Subscribe to an event - * @param {string} name - name of the event - * @param {(any) => void} callback - callback to call when the event is emitted - @returns {function()} unsubscribeMethod - method to unsubscribe from the event - */ - On: (name, callback) => { - return wails.Events.On(name, callback); - }, - /** - * Subscribe to an event once - * @param {string} name - name of the event - * @param {(any) => void} callback - callback to call when the event is emitted - * @returns {function()} unsubscribeMethod - method to unsubscribe from the event - */ - Once: (name, callback) => { - return wails.Events.Once(name, callback); - }, - /** - * Subscribe to an event multiple times - * @param {string} name - name of the event - * @param {(any) => void} callback - callback to call when the event is emitted - * @param {number} count - number of times to call the callback - * @returns {Promise} unsubscribeMethod - method to unsubscribe from the event - */ - OnMultiple: (name, callback, count) => { - return wails.Events.OnMultiple(name, callback, count); - }, - /** - * Unsubscribe from an event - * @param {string} name - name of the event to unsubscribe from - * @param {...string} additionalNames - additional names of events to unsubscribe from - */ - Off: (name, ...additionalNames) => { - wails.Events.Off(name, additionalNames); - }, - /** - * Unsubscribe all listeners from all events - */ - OffAll: () => { - wails.Events.OffAll(); - }, - - Windows: EventTypes.Windows, - Mac: EventTypes.Mac, - Common: EventTypes.Common, - -}; diff --git a/v3/internal/runtime/desktop/api/index.js b/v3/internal/runtime/desktop/api/index.js deleted file mode 100644 index 46a46b4b226..00000000000 --- a/v3/internal/runtime/desktop/api/index.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - _ __ _ __ -| | / /___ _(_) /____ -| | /| / / __ `/ / / ___/ -| |/ |/ / /_/ / / (__ ) -|__/|__/\__,_/_/_/____/ -The electron alternative for Go -(c) Lea Anthony 2019-present -*/ -/* jshint esversion: 9 */ - -import * as Clipboard from "./clipboard"; -import * as Application from "./application"; -import * as Screens from "./screens"; -import * as Dialogs from "./dialogs"; -import * as Events from "./events"; -import * as Window from "./window"; - -export { Clipboard, Application, Screens, Dialogs, Events, Window }; - -/** - * Call a plugin method - * @param {string} pluginName - name of the plugin - * @param {string} methodName - name of the method - * @param {...any} args - arguments to pass to the method - * @returns {Promise} - promise that resolves with the result - */ -export const Plugin = (pluginName, methodName, ...args) => { - return wails.Plugin(pluginName, methodName, ...args); -}; - - diff --git a/v3/internal/runtime/desktop/api/screens.js b/v3/internal/runtime/desktop/api/screens.js deleted file mode 100644 index f1e518d1579..00000000000 --- a/v3/internal/runtime/desktop/api/screens.js +++ /dev/null @@ -1,38 +0,0 @@ -/* - _ __ _ __ -| | / /___ _(_) /____ -| | /| / / __ `/ / / ___/ -| |/ |/ / /_/ / / (__ ) -|__/|__/\__,_/_/_/____/ -The electron alternative for Go -(c) Lea Anthony 2019-present -*/ - -/* jshint esversion: 9 */ - -/** - * The Screens API provides methods to interact with the system screens/monitors. - */ -export const Screens = { - /** - * Get the primary screen - * @returns {Promise} - */ - GetPrimary: () => { - return wails.Screens.GetPrimary(); - }, - /** - * Get all screens - * @returns {Promise} - */ - GetAll: () => { - return wails.Screens.GetAll(); - }, - /** - * Get the current screen - * @returns {Promise} - */ - GetCurrent: () => { - return wails.Screens.GetCurrent(); - }, -}; \ No newline at end of file diff --git a/v3/internal/runtime/desktop/api/window.js b/v3/internal/runtime/desktop/api/window.js deleted file mode 100644 index f6f97aee791..00000000000 --- a/v3/internal/runtime/desktop/api/window.js +++ /dev/null @@ -1,159 +0,0 @@ -/* - _ __ _ __ -| | / /___ _(_) /____ -| | /| / / __ `/ / / ___/ -| |/ |/ / /_/ / / (__ ) -|__/|__/\__,_/_/_/____/ -The electron alternative for Go -(c) Lea Anthony 2019-present -*/ - -/* jshint esversion: 9 */ - - -/** - * The Window API provides methods to interact with the window. - */ -export const Window = { - /** - * Center the window. - */ - Center: () => void wails.Window.Center(), - /** - * Set the window title. - * @param title - */ - SetTitle: (title) => void wails.Window.SetTitle(title), - - /** - * Makes the window fullscreen. - */ - Fullscreen: () => void wails.Window.Fullscreen(), - - /** - * Unfullscreen the window. - */ - UnFullscreen: () => void wails.Window.UnFullscreen(), - - /** - * Set the window size. - * @param {number} width The window width - * @param {number} height The window height - */ - SetSize: (width, height) => void wails.Window.SetSize(width, height), - - /** - * Get the window size. - * @returns {Promise} The window size - */ - Size: () => { - return wails.Window.Size(); - }, - - /** - * Set the window maximum size. - * @param {number} width - * @param {number} height - */ - SetMaxSize: (width, height) => void wails.Window.SetMaxSize(width, height), - - /** - * Set the window minimum size. - * @param {number} width - * @param {number} height - */ - SetMinSize: (width, height) => void wails.Window.SetMinSize(width, height), - - /** - * Set window to be always on top. - * @param {boolean} onTop Whether the window should be always on top - */ - SetAlwaysOnTop: (onTop) => void wails.Window.SetAlwaysOnTop(onTop), - - /** - * Set the window position relative to the current monitor. - * @param {number} x - * @param {number} y - */ - SetRelativePosition: (x, y) => void wails.Window.SetRelativePosition(x, y), - - /** - * Get the window position relative to the current monitor. - * @returns {Promise} The window position - */ - RelativePosition: () => { - return wails.Window.RelativePosition(); - }, - - /** - * Set the absolute window position. - * @param {number} x - * @param {number} y - */ - SetAbsolutePosition: (x, y) => void wails.Window.SetAbsolutePosition(x, y), - - /** - * Get the absolute window position. - * @returns {Promise} The window position - */ - AbsolutePosition: () => { - return wails.Window.AbsolutePosition(); - }, - - /** - * Get the screen the window is on. - * @returns {Promise} - */ - Screen: () => { - return wails.Window.Screen(); - }, - - /** - * Hide the window - */ - Hide: () => void wails.Window.Hide(), - - /** - * Maximise the window - */ - Maximise: () => void wails.Window.Maximise(), - - /** - * Show the window - */ - Show: () => void wails.Window.Show(), - - /** - * Close the window - */ - Close: () => void wails.Window.Close(), - - /** - * Toggle the window maximise state - */ - ToggleMaximise: () => void wails.Window.ToggleMaximise(), - - /** - * Unmaximise the window - */ - UnMaximise: () => void wails.Window.UnMaximise(), - - /** - * Minimise the window - */ - Minimise: () => void wails.Window.Minimise(), - - /** - * Unminimise the window - */ - UnMinimise: () => void wails.Window.UnMinimise(), - - /** - * Set the background colour of the window. - * @param {number} r - The red value between 0 and 255 - * @param {number} g - The green value between 0 and 255 - * @param {number} b - The blue value between 0 and 255 - * @param {number} a - The alpha value between 0 and 255 - */ - SetBackgroundColour: (r, g, b, a) => void wails.Window.SetBackgroundColour(r, g, b, a), -}; diff --git a/v3/internal/runtime/desktop/application.js b/v3/internal/runtime/desktop/application.js deleted file mode 100644 index 097f322e915..00000000000 --- a/v3/internal/runtime/desktop/application.js +++ /dev/null @@ -1,43 +0,0 @@ -/* - _ __ _ __ -| | / /___ _(_) /____ -| | /| / / __ `/ / / ___/ -| |/ |/ / /_/ / / (__ ) -|__/|__/\__,_/_/_/____/ -The electron alternative for Go -(c) Lea Anthony 2019-present -*/ - -/* jshint esversion: 9 */ - -import {newRuntimeCallerWithID, objectNames} from "./runtime"; - -let call = newRuntimeCallerWithID(objectNames.Application); - -let methods = { - Hide: 0, - Show: 1, - Quit: 2, -} - -/** - * Hide the application - */ -export function Hide() { - void call(methods.Hide); -} - -/** - * Show the application - */ -export function Show() { - void call(methods.Show); -} - - -/** - * Quit the application - */ -export function Quit() { - void call(methods.Quit); -} \ No newline at end of file diff --git a/v3/internal/runtime/desktop/calls.js b/v3/internal/runtime/desktop/calls.js deleted file mode 100644 index a9e60b716cf..00000000000 --- a/v3/internal/runtime/desktop/calls.js +++ /dev/null @@ -1,107 +0,0 @@ -/* - _ __ _ __ -| | / /___ _(_) /____ -| | /| / / __ `/ / / ___/ -| |/ |/ / /_/ / / (__ ) -|__/|__/\__,_/_/_/____/ -The electron alternative for Go -(c) Lea Anthony 2019-present -*/ - -/* jshint esversion: 9 */ - -import {newRuntimeCallerWithID, objectNames} from "./runtime"; - -import { nanoid } from 'nanoid/non-secure'; - -let call = newRuntimeCallerWithID(objectNames.Call); - -let CallBinding = 0; - -let callResponses = new Map(); - -function generateID() { - let result; - do { - result = nanoid(); - } while (callResponses.has(result)); - return result; -} - -export function callCallback(id, data, isJSON) { - let p = callResponses.get(id); - if (p) { - if (isJSON) { - p.resolve(JSON.parse(data)); - } else { - p.resolve(data); - } - callResponses.delete(id); - } -} - -export function callErrorCallback(id, message) { - let p = callResponses.get(id); - if (p) { - p.reject(message); - callResponses.delete(id); - } -} - -function callBinding(type, options) { - return new Promise((resolve, reject) => { - let id = generateID(); - options = options || {}; - options["call-id"] = id; - - callResponses.set(id, {resolve, reject}); - call(type, options).catch((error) => { - reject(error); - callResponses.delete(id); - }); - }); -} - -export function Call(options) { - return callBinding(CallBinding, options); -} - -export function CallByName(name, ...args) { - - // Ensure first argument is a string and has 2 dots - if (typeof name !== "string" || name.split(".").length !== 3) { - throw new Error("CallByName requires a string in the format 'package.struct.method'"); - } - // Split inputs - let parts = name.split("."); - - return callBinding(CallBinding, { - packageName: parts[0], - structName: parts[1], - methodName: parts[2], - args: args, - }); -} - -export function CallByID(methodID, ...args) { - return callBinding(CallBinding, { - methodID: methodID, - args: args, - }); -} - -/** - * Call a plugin method - * @param {string} pluginName - name of the plugin - * @param {string} methodName - name of the method - * @param {...any} args - arguments to pass to the method - * @returns {Promise} - promise that resolves with the result - */ -export function Plugin(pluginName, methodName, ...args) { - return callBinding(CallBinding, { - packageName: "wails-plugins", - structName: pluginName, - methodName: methodName, - args: args, - }); -} \ No newline at end of file diff --git a/v3/internal/runtime/desktop/clipboard.js b/v3/internal/runtime/desktop/clipboard.js deleted file mode 100644 index cc9eb0373d7..00000000000 --- a/v3/internal/runtime/desktop/clipboard.js +++ /dev/null @@ -1,33 +0,0 @@ -/* - _ __ _ __ -| | / /___ _(_) /____ -| | /| / / __ `/ / / ___/ -| |/ |/ / /_/ / / (__ ) -|__/|__/\__,_/_/_/____/ -The electron alternative for Go -(c) Lea Anthony 2019-present -*/ - -/* jshint esversion: 9 */ - -import {newRuntimeCallerWithID, objectNames} from "./runtime"; - -let call = newRuntimeCallerWithID(objectNames.Clipboard); - -let ClipboardSetText = 0; -let ClipboardText = 1; - -/** - * Set the Clipboard text - */ -export function SetText(text) { - void call(ClipboardSetText, {text}); -} - -/** - * Get the Clipboard text - * @returns {Promise} - */ -export function Text() { - return call(ClipboardText); -} \ No newline at end of file diff --git a/v3/internal/runtime/desktop/dialogs.js b/v3/internal/runtime/desktop/dialogs.js deleted file mode 100644 index 2865b7d844b..00000000000 --- a/v3/internal/runtime/desktop/dialogs.js +++ /dev/null @@ -1,129 +0,0 @@ -/* - _ __ _ __ -| | / /___ _(_) /____ -| | /| / / __ `/ / / ___/ -| |/ |/ / /_/ / / (__ ) -|__/|__/\__,_/_/_/____/ -The electron alternative for Go -(c) Lea Anthony 2019-present -*/ - -/* jshint esversion: 9 */ - -/** - * @typedef {import("./api/types").MessageDialogOptions} MessageDialogOptions - * @typedef {import("./api/types").OpenDialogOptions} OpenDialogOptions - * @typedef {import("./api/types").SaveDialogOptions} SaveDialogOptions - */ - -import {newRuntimeCallerWithID, objectNames} from "./runtime"; - -import { nanoid } from 'nanoid/non-secure'; - -let call = newRuntimeCallerWithID(objectNames.Dialog); - -let DialogInfo = 0; -let DialogWarning = 1; -let DialogError = 2; -let DialogQuestion = 3; -let DialogOpenFile = 4; -let DialogSaveFile = 5; - - -let dialogResponses = new Map(); - -function generateID() { - let result; - do { - result = nanoid(); - } while (dialogResponses.has(result)); - return result; -} - -export function dialogCallback(id, data, isJSON) { - let p = dialogResponses.get(id); - if (p) { - if (isJSON) { - p.resolve(JSON.parse(data)); - } else { - p.resolve(data); - } - dialogResponses.delete(id); - } -} -export function dialogErrorCallback(id, message) { - let p = dialogResponses.get(id); - if (p) { - p.reject(message); - dialogResponses.delete(id); - } -} - -function dialog(type, options) { - return new Promise((resolve, reject) => { - let id = generateID(); - options = options || {}; - options["dialog-id"] = id; - dialogResponses.set(id, {resolve, reject}); - call(type, options).catch((error) => { - reject(error); - dialogResponses.delete(id); - }); - }); -} - - -/** - * Shows an Info dialog with the given options. - * @param {MessageDialogOptions} options - * @returns {Promise} The label of the button pressed - */ -export function Info(options) { - return dialog(DialogInfo, options); -} - -/** - * Shows a Warning dialog with the given options. - * @param {MessageDialogOptions} options - * @returns {Promise} The label of the button pressed - */ -export function Warning(options) { - return dialog(DialogWarning, options); -} - -/** - * Shows an Error dialog with the given options. - * @param {MessageDialogOptions} options - * @returns {Promise} The label of the button pressed - */ -export function Error(options) { - return dialog(DialogError, options); -} - -/** - * Shows a Question dialog with the given options. - * @param {MessageDialogOptions} options - * @returns {Promise} The label of the button pressed - */ -export function Question(options) { - return dialog(DialogQuestion, options); -} - -/** - * Shows an Open dialog with the given options. - * @param {OpenDialogOptions} options - * @returns {Promise} Returns the selected file or an array of selected files if AllowsMultipleSelection is true. A blank string is returned if no file was selected. - */ -export function OpenFile(options) { - return dialog(DialogOpenFile, options); -} - -/** - * Shows a Save dialog with the given options. - * @param {SaveDialogOptions} options - * @returns {Promise} Returns the selected file. A blank string is returned if no file was selected. - */ -export function SaveFile(options) { - return dialog(DialogSaveFile, options); -} - diff --git a/v3/internal/runtime/desktop/events.js b/v3/internal/runtime/desktop/events.js deleted file mode 100644 index 40e40ebd740..00000000000 --- a/v3/internal/runtime/desktop/events.js +++ /dev/null @@ -1,194 +0,0 @@ -/* - _ __ _ __ -| | / /___ _(_) /____ -| | /| / / __ `/ / / ___/ -| |/ |/ / /_/ / / (__ ) -|__/|__/\__,_/_/_/____/ -The electron alternative for Go -(c) Lea Anthony 2019-present -*/ - -/* jshint esversion: 9 */ - -/** - * @typedef {import("./api/types").WailsEvent} WailsEvent - */ - -import {newRuntimeCallerWithID, objectNames} from "./runtime"; - -let call = newRuntimeCallerWithID(objectNames.Events); -let EventEmit = 0; - -/** - * The Listener class defines a listener! :-) - * - * @class Listener - */ -class Listener { - /** - * Creates an instance of Listener. - * @param {string} eventName - * @param {function} callback - * @param {number} maxCallbacks - * @memberof Listener - */ - constructor(eventName, callback, maxCallbacks) { - this.eventName = eventName; - // Default of -1 means infinite - this.maxCallbacks = maxCallbacks || -1; - // Callback invokes the callback with the given data - // Returns true if this listener should be destroyed - this.Callback = (data) => { - callback(data); - // If maxCallbacks is infinite, return false (do not destroy) - if (this.maxCallbacks === -1) { - return false; - } - // Decrement maxCallbacks. Return true if now 0, otherwise false - this.maxCallbacks -= 1; - return this.maxCallbacks === 0; - }; - } -} - - -/** - * WailsEvent defines a custom event. It is passed to event listeners. - * - * @class WailsEvent - * @property {string} name - Name of the event - * @property {any} data - Data associated with the event - */ -export class WailsEvent { - /** - * Creates an instance of WailsEvent. - * @param {string} name - Name of the event - * @param {any=null} data - Data associated with the event - * @memberof WailsEvent - */ - constructor(name, data = null) { - this.name = name; - this.data = data; - } -} - -export const eventListeners = new Map(); - -/** - * Registers an event listener that will be invoked `maxCallbacks` times before being destroyed - * - * @export - * @param {string} eventName - * @param {function(WailsEvent): void} callback - * @param {number} maxCallbacks - * @returns {function} A function to cancel the listener - */ -export function OnMultiple(eventName, callback, maxCallbacks) { - let listeners = eventListeners.get(eventName) || []; - const thisListener = new Listener(eventName, callback, maxCallbacks); - listeners.push(thisListener); - eventListeners.set(eventName, listeners); - return () => listenerOff(thisListener); -} - -/** - * Registers an event listener that will be invoked every time the event is emitted - * - * @export - * @param {string} eventName - * @param {function(WailsEvent): void} callback - * @returns {function} A function to cancel the listener - */ -export function On(eventName, callback) { - return OnMultiple(eventName, callback, -1); -} - -/** - * Registers an event listener that will be invoked once then destroyed - * - * @export - * @param {string} eventName - * @param {function(WailsEvent): void} callback - @returns {function} A function to cancel the listener - */ -export function Once(eventName, callback) { - return OnMultiple(eventName, callback, 1); -} - -/** - * listenerOff unregisters a listener previously registered with On - * - * @param {Listener} listener - */ -function listenerOff(listener) { - const eventName = listener.eventName; - // Remove local listener - let listeners = eventListeners.get(eventName).filter(l => l !== listener); - if (listeners.length === 0) { - eventListeners.delete(eventName); - } else { - eventListeners.set(eventName, listeners); - } -} - -/** - * dispatches an event to all listeners - * - * @export - * @param {WailsEvent} event - */ -export function dispatchWailsEvent(event) { - let listeners = eventListeners.get(event.name); - if (listeners) { - // iterate listeners and call callback. If callback returns true, remove listener - let toRemove = []; - listeners.forEach(listener => { - let remove = listener.Callback(event); - if (remove) { - toRemove.push(listener); - } - }); - // remove listeners - if (toRemove.length > 0) { - listeners = listeners.filter(l => !toRemove.includes(l)); - if (listeners.length === 0) { - eventListeners.delete(event.name); - } else { - eventListeners.set(event.name, listeners); - } - } - } -} - -/** - * Off unregisters a listener previously registered with On, - * optionally multiple listeners can be unregistered via `additionalEventNames` - * - [v3 CHANGE] Off only unregisters listeners within the current window - * - * @param {string} eventName - * @param {...string} additionalEventNames - */ -export function Off(eventName, ...additionalEventNames) { - let eventsToRemove = [eventName, ...additionalEventNames]; - eventsToRemove.forEach(eventName => { - eventListeners.delete(eventName); - }); -} - -/** - * OffAll unregisters all listeners - * [v3 CHANGE] OffAll only unregisters listeners within the current window - * - */ -export function OffAll() { - eventListeners.clear(); -} - -/** - * Emit an event - * @param {WailsEvent} event The event to emit - */ -export function Emit(event) { - void call(EventEmit, event); -} \ No newline at end of file diff --git a/v3/internal/runtime/desktop/invoke.js b/v3/internal/runtime/desktop/invoke.js deleted file mode 100644 index b8a2daa1b8b..00000000000 --- a/v3/internal/runtime/desktop/invoke.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - _ __ _ __ -| | / /___ _(_) /____ -| | /| / / __ `/ / / ___/ -| |/ |/ / /_/ / / (__ ) -|__/|__/\__,_/_/_/____/ -The electron alternative for Go -(c) Lea Anthony 2019-present -*/ - -/* jshint esversion: 9 */ - -// defined in the Taskfile -export let invoke = function(input) { - if(WINDOWS) { - chrome.webview.postMessage(input); - } else { - webkit.messageHandlers.external.postMessage(input); - } -} diff --git a/v3/internal/runtime/desktop/main.js b/v3/internal/runtime/desktop/main.js index 66709a490b4..3546a81538c 100644 --- a/v3/internal/runtime/desktop/main.js +++ b/v3/internal/runtime/desktop/main.js @@ -10,39 +10,32 @@ The electron alternative for Go /* jshint esversion: 9 */ -import * as Clipboard from './clipboard'; -import * as Application from './application'; -import * as Screens from './screens'; -import * as System from './system'; -import * as Browser from './browser'; -import {Plugin, Call, callErrorCallback, callCallback, CallByID, CallByName} from "./calls"; -import {clientId} from './runtime'; -import {newWindow} from "./window"; -import {dispatchWailsEvent, Emit, Off, OffAll, On, Once, OnMultiple} from "./events"; -import {dialogCallback, dialogErrorCallback, Error, Info, OpenFile, Question, SaveFile, Warning,} from "./dialogs"; -import {setupContextMenus} from "./contextmenu"; -import {reloadWML} from "./wml"; -import {setupDrag, endDrag, setResizable} from "./drag"; +import * as Clipboard from './@wailsio/runtime/clipboard'; +import * as Application from './@wailsio/runtime/application'; +import * as Screens from './@wailsio/runtime/screens'; +import * as System from './@wailsio/runtime/system'; +import * as Browser from './@wailsio/runtime/browser'; +import * as Window from './@wailsio/runtime/window'; +import {Plugin, Call, errorHandler as callErrorHandler, resultHandler as callResultHandler, ByID, ByName} from "./@wailsio/runtime/calls"; +import {clientId} from './@wailsio/runtime/runtime'; +import {dispatchWailsEvent, Emit, Off, OffAll, On, Once, OnMultiple} from "./@wailsio/runtime/events"; +import {dialogCallback, dialogErrorCallback, Error, Info, OpenFile, Question, SaveFile, Warning} from "./@wailsio/runtime/dialogs"; +import {setupContextMenus} from './@wailsio/runtime/contextmenu'; +import {reloadWML} from './@wailsio/runtime/wml'; +import {setupDrag, endDrag, setResizable} from './@wailsio/runtime/drag'; window.wails = { ...newRuntime(null), - Capabilities: {}, clientId: clientId, }; -fetch("/wails/capabilities").then((response) => { - response.json().then((data) => { - window.wails.Capabilities = data; - }); -}); - // Internal wails endpoints window._wails = { dialogCallback, dialogErrorCallback, dispatchWailsEvent, - callCallback, - callErrorCallback, + callErrorHandler, + callResultHandler, endDrag, setResizable, }; @@ -54,17 +47,16 @@ export function newRuntime(windowName) { }, Application: { ...Application, - GetWindowByName(windowName) { - return newRuntime(windowName); - } }, System, Screens, Browser, - Call, - CallByID, - CallByName, - Plugin, + Call: { + Call, + ByID, + ByName, + Plugin, + }, WML: { Reload: reloadWML, }, @@ -84,14 +76,12 @@ export function newRuntime(windowName) { Off, OffAll, }, - Window: newWindow(windowName), + Window: { + ...Window.Get('') + }, }; } -if (DEBUG) { - console.log("Wails v3.0.0 Debug Mode Enabled"); -} - setupContextMenus(); setupDrag(); diff --git a/v3/internal/runtime/desktop/system.js b/v3/internal/runtime/desktop/system.js deleted file mode 100644 index d1f29e4035a..00000000000 --- a/v3/internal/runtime/desktop/system.js +++ /dev/null @@ -1,25 +0,0 @@ -/* - _ __ _ __ -| | / /___ _(_) /____ -| | /| / / __ `/ / / ___/ -| |/ |/ / /_/ / / (__ ) -|__/|__/\__,_/_/_/____/ -The electron alternative for Go -(c) Lea Anthony 2019-present -*/ - -/* jshint esversion: 9 */ - -import {newRuntimeCallerWithID, objectNames} from "./runtime"; - -let call = newRuntimeCallerWithID(objectNames.System); - -let SystemIsDarkMode = 0; - -/** - * Determines if the system is currently using dark mode - * @returns {Promise} - */ -export function IsDarkMode() { - return call(SystemIsDarkMode); -} \ No newline at end of file diff --git a/v3/internal/runtime/desktop/window.js b/v3/internal/runtime/desktop/window.js deleted file mode 100644 index f255ae42ea1..00000000000 --- a/v3/internal/runtime/desktop/window.js +++ /dev/null @@ -1,228 +0,0 @@ -/* - _ __ _ __ -| | / /___ _(_) /____ -| | /| / / __ `/ / / ___/ -| |/ |/ / /_/ / / (__ ) -|__/|__/\__,_/_/_/____/ -The electron alternative for Go -(c) Lea Anthony 2019-present -*/ - -/* jshint esversion: 9 */ - -/** - * @typedef {import("../api/types").Size} Size - * @typedef {import("../api/types").Position} Position - * @typedef {import("../api/types").Screen} Screen - */ - -import {newRuntimeCallerWithID, objectNames} from "./runtime"; - -let WindowCenter = 0; -let WindowSetTitle = 1; -let WindowFullscreen = 2; -let WindowUnFullscreen = 3; -let WindowSetSize = 4; -let WindowSize = 5; -let WindowSetMaxSize = 6; -let WindowSetMinSize = 7; -let WindowSetAlwaysOnTop = 8; -let WindowSetRelativePosition = 9; -let WindowRelativePosition = 10; -let WindowScreen = 11; -let WindowHide = 12; -let WindowMaximise = 13; -let WindowUnMaximise = 14; -let WindowToggleMaximise = 15; -let WindowMinimise = 16; -let WindowUnMinimise = 17; -let WindowRestore = 18; -let WindowShow = 19; -let WindowClose = 20; -let WindowSetBackgroundColour = 21; -let WindowSetResizable = 22; -let WindowWidth = 23; -let WindowHeight = 24; -let WindowZoomIn = 25; -let WindowZoomOut = 26; -let WindowZoomReset = 27; -let WindowGetZoomLevel = 28; -let WindowSetZoomLevel = 29; - -export function newWindow(windowName) { - let call = newRuntimeCallerWithID(objectNames.Window, windowName); - return { - - /** - * Centers the window. - */ - Center: () => void call(WindowCenter), - - /** - * Set the window title. - * @param title - */ - SetTitle: (title) => void call(WindowSetTitle, {title}), - - /** - * Makes the window fullscreen. - */ - Fullscreen: () => void call(WindowFullscreen), - - /** - * Unfullscreen the window. - */ - UnFullscreen: () => void call(WindowUnFullscreen), - - /** - * Set the window size. - * @param {number} width The window width - * @param {number} height The window height - */ - SetSize: (width, height) => call(WindowSetSize, {width,height}), - - /** - * Get the window size. - * @returns {Promise} The window size - */ - Size: () => { return call(WindowSize); }, - - /** - * Set the window maximum size. - * @param {number} width - * @param {number} height - */ - SetMaxSize: (width, height) => void call(WindowSetMaxSize, {width,height}), - - /** - * Set the window minimum size. - * @param {number} width - * @param {number} height - */ - SetMinSize: (width, height) => void call(WindowSetMinSize, {width,height}), - - /** - * Set window to be always on top. - * @param {boolean} onTop Whether the window should be always on top - */ - SetAlwaysOnTop: (onTop) => void call(WindowSetAlwaysOnTop, {alwaysOnTop:onTop}), - - /** - * Set the window relative position. - * @param {number} x - * @param {number} y - */ - SetRelativePosition: (x, y) => call(WindowSetRelativePosition, {x,y}), - - /** - * Get the window position. - * @returns {Promise} The window position - */ - RelativePosition: () => { return call(WindowRelativePosition); }, - - /** - * Get the screen the window is on. - * @returns {Promise} - */ - Screen: () => { return call(WindowScreen); }, - - /** - * Hide the window - */ - Hide: () => void call(WindowHide), - - /** - * Maximise the window - */ - Maximise: () => void call(WindowMaximise), - - /** - * Show the window - */ - Show: () => void call(WindowShow), - - /** - * Close the window - */ - Close: () => void call(WindowClose), - - /** - * Toggle the window maximise state - */ - ToggleMaximise: () => void call(WindowToggleMaximise), - - /** - * Unmaximise the window - */ - UnMaximise: () => void call(WindowUnMaximise), - - /** - * Minimise the window - */ - Minimise: () => void call(WindowMinimise), - - /** - * Unminimise the window - */ - UnMinimise: () => void call(WindowUnMinimise), - - /** - * Restore the window - */ - Restore: () => void call(WindowRestore), - - /** - * Set the background colour of the window. - * @param {number} r - A value between 0 and 255 - * @param {number} g - A value between 0 and 255 - * @param {number} b - A value between 0 and 255 - * @param {number} a - A value between 0 and 255 - */ - SetBackgroundColour: (r, g, b, a) => void call(WindowSetBackgroundColour, {r, g, b, a}), - - /** - * Set whether the window can be resized or not - * @param {boolean} resizable - */ - SetResizable: (resizable) => void call(WindowSetResizable, {resizable}), - - /** - * Get the window width - * @returns {Promise} - */ - Width: () => { return call(WindowWidth); }, - - /** - * Get the window height - * @returns {Promise} - */ - Height: () => { return call(WindowHeight); }, - - /** - * Zoom in the window - */ - ZoomIn: () => void call(WindowZoomIn), - - /** - * Zoom out the window - */ - ZoomOut: () => void call(WindowZoomOut), - - /** - * Reset the window zoom - */ - ZoomReset: () => void call(WindowZoomReset), - - /** - * Get the window zoom - * @returns {Promise} - */ - GetZoomLevel: () => { return call(WindowGetZoomLevel); }, - - /** - * Set the window zoom level - * @param {number} zoomLevel - */ - SetZoomLevel: (zoomLevel) => void call(WindowSetZoomLevel, {zoomLevel}), - }; -} diff --git a/v3/internal/runtime/runtime.js b/v3/internal/runtime/runtime.js new file mode 100644 index 00000000000..01fae4e203a --- /dev/null +++ b/v3/internal/runtime/runtime.js @@ -0,0 +1 @@ +(()=>{var Se=Object.defineProperty;var b=(e,t)=>{for(var n in t)Se(e,n,{get:t[n],enumerable:!0})};var N={};b(N,{SetText:()=>Le,Text:()=>Oe});var De="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var g=(e=21)=>{let t="",n=e;for(;n--;)t+=De[Math.random()*64|0];return t};var Ee=window.location.origin+"/wails/runtime",s={Call:0,Clipboard:1,Application:2,Events:3,ContextMenu:4,Dialog:5,Window:6,Screens:7,System:8,Browser:9},z=g();function l(e,t){return function(n,o=null){return Re(e,n,t,o)}}function Re(e,t,n,o){let r=new URL(Ee);r.searchParams.append("object",e),r.searchParams.append("method",t);let i={headers:{}};return n&&(i.headers["x-wails-window-name"]=n),o&&r.searchParams.append("args",JSON.stringify(o)),i.headers["x-wails-client-id"]=z,new Promise((c,p)=>{fetch(r,i).then(a=>{if(a.ok)return a.headers.get("Content-Type")&&a.headers.get("Content-Type").indexOf("application/json")!==-1?a.json():a.text();p(Error(a.statusText))}).then(a=>c(a)).catch(a=>p(a))})}var V=l(s.Clipboard,""),ye=0,We=1;function Le(e){return V(ye,{text:e})}function Oe(){return V(We)}var P={};b(P,{Hide:()=>ze,Quit:()=>Te,Show:()=>Ne});var T=l(s.Application),Ie=0,ke=1,Ae=2;function ze(){return T(Ie)}function Ne(){return T(ke)}function Te(){return T(Ae)}var H={};b(H,{GetAll:()=>je,GetCurrent:()=>Ue,GetPrimary:()=>Fe});var B=l(s.Screens,""),Pe=0,Be=1,He=2;function je(){return B(Pe)}function Fe(){return B(Be)}function Ue(){return B(He)}var j={};b(j,{Capabilities:()=>Xe,Environment:()=>J,IsAMD64:()=>Ve,IsARM:()=>qe,IsARM64:()=>Je,IsDarkMode:()=>Ye,IsLinux:()=>Ze,IsMac:()=>Qe,IsWindows:()=>v,invoke:()=>M});var q=l(s.System,""),_e=0,Ge=1;function Ye(){return q(_e)}async function Xe(){return fetch("/wails/capabilities").json()}function J(){return q(Ge)}var M=null,d=null;J().then(e=>{d=e,M=v()?window.chrome.webview.postMessage:window.webkit.messageHandlers.external.postMessage}).catch(e=>{});function v(){return d.OS==="windows"}function Ze(){return d.OS==="linux"}function Qe(){return d.OS==="darwin"}function Ve(){return d.Arch==="amd64"}function qe(){return d.Arch==="arm"}function Je(){return d.Arch==="arm64"}var F={};b(F,{OpenURL:()=>et});var $e=l(s.Browser,""),Ke=0;function et(e){return $e(Ke,{url:e})}var tt=0,nt=1,ot=2,rt=3,it=4,st=5,lt=6,at=7,ct=8,ut=9,ft=10,dt=11,mt=12,pt=13,wt=14,gt=15,ht=16,xt=17,Ct=18,bt=19,Mt=20,vt=21,St=22,Dt=23,Et=24,Rt=25,yt=26,Wt=27,Lt=28,Ot=29,Mn=l(s.Window,"");function $(e){return{Get:t=>$(l(s.Window,t)),Center:()=>e(tt),SetTitle:t=>e(nt,{title:t}),Fullscreen:()=>e(ot),UnFullscreen:()=>e(rt),SetSize:(t,n)=>e(it,{width:t,height:n}),Size:()=>e(st),SetMaxSize:(t,n)=>e(lt,{width:t,height:n}),SetMinSize:(t,n)=>e(at,{width:t,height:n}),SetAlwaysOnTop:t=>e(ct,{alwaysOnTop:t}),SetRelativePosition:(t,n)=>e(ut,{x:t,y:n}),RelativePosition:()=>e(ft),Screen:()=>e(dt),Hide:()=>e(mt),Maximise:()=>e(pt),UnMaximise:()=>e(wt),ToggleMaximise:()=>e(gt),Minimise:()=>e(ht),UnMinimise:()=>e(xt),Restore:()=>e(Ct),Show:()=>e(bt),Close:()=>e(Mt),SetBackgroundColour:(t,n,o,r)=>e(vt,{r:t,g:n,b:o,a:r}),SetResizable:t=>e(St,{resizable:t}),Width:()=>e(Dt),Height:()=>e(Et),ZoomIn:()=>e(Rt),ZoomOut:()=>e(yt),ZoomReset:()=>e(Wt),GetZoomLevel:()=>e(Lt),SetZoomLevel:t=>e(Ot,{zoomLevel:t})}}function S(e){return $(l(s.Window,e))}function K(e){let t=new Map;for(let n in e)typeof e[n]=="function"&&t.set(n,e[n]);return t}var vn={...S("")};var R=0,kt=l(s.Call,""),D=new Map;window._wails=window._wails||{};window._wails.callCallback=U;window._wails.callErrorCallback=_;function At(){let e;do e=g();while(D.has(e));return e}function U(e,t,n){let o=ee(e);o&&o.resolve(n?JSON.parse(t):t)}function _(e,t){let n=ee(e);n&&n.reject(t)}function ee(e){let t=D.get(e);return D.delete(e),t}function y(e,t={}){return new Promise((n,o)=>{let r=At();t["call-id"]=r,D.set(r,{resolve:n,reject:o}),kt(e,t).catch(i=>{o(i),D.delete(r)})})}function te(e){return y(R,e)}function ne(e,...t){if(typeof e!="string"||e.split(".").length!==3)throw new Error("CallByName requires a string in the format 'package.struct.method'");let[n,o,r]=e.split(".");return y(R,{packageName:n,structName:o,methodName:r,args:t})}function oe(e,...t){return y(R,{methodID:e,args:t})}function re(e,t,...n){return y(R,{packageName:"wails-plugins",structName:e,methodName:t,args:n})}var zt=l(s.Events,""),Nt=0,u=new Map,G=class{constructor(t,n,o){this.eventName=t,this.maxCallbacks=o||-1,this.Callback=r=>(n(r),this.maxCallbacks===-1?!1:(this.maxCallbacks-=1,this.maxCallbacks===0))}},W=class{constructor(t,n=null){this.name=t,this.data=n}};window._wails=window._wails||{};window._wails.dispatchWailsEvent=Y;function Y(e){let t=u.get(e.name);if(t){let n=t.filter(o=>{if(o.Callback(e))return!0});n.length>0&&(t=t.filter(o=>!n.includes(o)),t.length===0?u.delete(e.name):u.set(e.name,t))}}function L(e,t,n){let o=u.get(e)||[],r=new G(e,t,n);return o.push(r),u.set(e,o),()=>Tt(r)}function ie(e,t){return L(e,t,-1)}function se(e,t){return L(e,t,1)}function Tt(e){let t=e.eventName,n=u.get(t).filter(o=>o!==e);n.length===0?u.delete(t):u.set(t,n)}function le(e,...t){[e,...t].forEach(o=>u.delete(o))}function ae(){u.clear()}function O(e){return zt(Nt,e)}var Pt=0,Bt=1,Ht=2,jt=3,Ft=4,Ut=5,_t=l(s.Dialog,""),m=new Map;function Gt(){let e;do e=g();while(m.has(e));return e}function h(e,t={}){let n=Gt();return t["dialog-id"]=n,new Promise((o,r)=>{m.set(n,{resolve:o,reject:r}),_t(e,t).catch(i=>{r(i),m.delete(n)})})}function ce(e,t,n){let o=m.get(e);o&&(n?o.resolve(JSON.parse(t)):o.resolve(t),m.delete(e))}function ue(e,t){let n=m.get(e);n&&(n.reject(t),m.delete(e))}var fe=e=>h(Pt,e),de=e=>h(Bt,e),me=e=>h(Ht,e),x=e=>h(jt,e),pe=e=>h(Ft,e),we=e=>h(Ut,e);var Yt=l(s.ContextMenu,""),Xt=0;function Zt(e,t,n,o){Yt(Xt,{id:e,x:t,y:n,data:o})}function ge(){window.addEventListener("contextmenu",Qt)}function Qt(e){let t=e.target,n=window.getComputedStyle(t).getPropertyValue("--custom-contextmenu");if(n=n?n.trim():"",n){e.preventDefault();let o=window.getComputedStyle(t).getPropertyValue("--custom-contextmenu-data");Zt(n,e.clientX,e.clientY,o);return}Vt(e)}function Vt(e){if(DEBUG)return;let t=e.target;switch(window.getComputedStyle(t).getPropertyValue("--default-contextmenu").trim()){case"show":return;case"hide":e.preventDefault();return;default:if(t.isContentEditable)return;let r=window.getSelection(),i=r.toString().length>0;if(i)for(let c=0;c{e.json().then(t=>{Ce=be(t)})});function Kt(e){let t=e.split("."),n=Ce;for(let o of t)if(n instanceof Map?n=n.get(o):n=n[o],n===void 0)break;return n}function I(e){return Kt(e)}var E=!1,k=null,Me=!1,en="auto";window._wails=window._wails||{};window._wails.setResizable=Z;window._wails.endDrag=A;function tn(e){let t=window.getComputedStyle(e.target).getPropertyValue("--webkit-app-region");return t&&t.trim()!=="drag"||e.buttons!==1?!1:e.detail===1}function ve(){window.addEventListener("mousedown",on),window.addEventListener("mousemove",ln),window.addEventListener("mouseup",sn)}function Z(e){Me=e}function A(){document.body.style.cursor="default",E=!1}function nn(){return k?(M(`resize:${k}`),!0):!1}function on(e){(v()&&nn()||tn(e))&&(E=!!rn(e))}function rn(e){return!(e.offsetX>e.target.clientWidth||e.offsetY>e.target.clientHeight)}function sn(e){(e.buttons!==void 0?e.buttons:e.which)>0&&A()}function f(e=en){document.documentElement.style.cursor=e,k=e}function ln(e){E=an(e),v()&&Me&&cn(e)}function an(e){let t=e.buttons!==void 0?e.buttons:e.which;return E&&t>0?(M("drag"),!1):E}function cn(e){let t=I("system.resizeHandleHeight")||5,n=I("system.resizeHandleWidth")||5,o=I("resizeCornerExtra")||10,r=window.outerWidth-e.clientX { + var __defProp = Object.defineProperty; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + + // desktop/@wailsio/runtime/clipboard.js + var clipboard_exports = {}; + __export(clipboard_exports, { + SetText: () => SetText, + Text: () => Text + }); + + // node_modules/nanoid/non-secure/index.js + var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"; + var nanoid = (size2 = 21) => { + let id = ""; + let i = size2; + while (i--) { + id += urlAlphabet[Math.random() * 64 | 0]; + } + return id; + }; + + // desktop/@wailsio/runtime/runtime.js + var runtimeURL = window.location.origin + "/wails/runtime"; + var objectNames = { + Call: 0, + Clipboard: 1, + Application: 2, + Events: 3, + ContextMenu: 4, + Dialog: 5, + Window: 6, + Screens: 7, + System: 8, + Browser: 9 + }; + var clientId = nanoid(); + function newRuntimeCallerWithID(object, windowName) { + return function(method, args = null) { + return runtimeCallWithID(object, method, windowName, args); + }; + } + function runtimeCallWithID(objectID, method, windowName, args) { + let url = new URL(runtimeURL); + url.searchParams.append("object", objectID); + url.searchParams.append("method", method); + let fetchOptions = { + headers: {} + }; + if (windowName) { + fetchOptions.headers["x-wails-window-name"] = windowName; + } + if (args) { + url.searchParams.append("args", JSON.stringify(args)); + } + fetchOptions.headers["x-wails-client-id"] = clientId; + return new Promise((resolve, reject) => { + fetch(url, fetchOptions).then((response) => { + if (response.ok) { + if (response.headers.get("Content-Type") && response.headers.get("Content-Type").indexOf("application/json") !== -1) { + return response.json(); + } else { + return response.text(); + } + } + reject(Error(response.statusText)); + }).then((data) => resolve(data)).catch((error) => reject(error)); + }); + } + + // desktop/@wailsio/runtime/clipboard.js + var call = newRuntimeCallerWithID(objectNames.Clipboard, ""); + var ClipboardSetText = 0; + var ClipboardText = 1; + function SetText(text) { + return call(ClipboardSetText, { text }); + } + function Text() { + return call(ClipboardText); + } + + // desktop/@wailsio/runtime/application.js + var application_exports = {}; + __export(application_exports, { + Hide: () => Hide, + Quit: () => Quit, + Show: () => Show + }); + var call2 = newRuntimeCallerWithID(objectNames.Application); + var HideMethod = 0; + var ShowMethod = 1; + var QuitMethod = 2; + function Hide() { + return call2(HideMethod); + } + function Show() { + return call2(ShowMethod); + } + function Quit() { + return call2(QuitMethod); + } + + // desktop/@wailsio/runtime/screens.js + var screens_exports = {}; + __export(screens_exports, { + GetAll: () => GetAll, + GetCurrent: () => GetCurrent, + GetPrimary: () => GetPrimary + }); + var call3 = newRuntimeCallerWithID(objectNames.Screens, ""); + var getAll = 0; + var getPrimary = 1; + var getCurrent = 2; + function GetAll() { + return call3(getAll); + } + function GetPrimary() { + return call3(getPrimary); + } + function GetCurrent() { + return call3(getCurrent); + } + + // desktop/@wailsio/runtime/system.js + var system_exports = {}; + __export(system_exports, { + Capabilities: () => Capabilities, + Environment: () => Environment, + IsAMD64: () => IsAMD64, + IsARM: () => IsARM, + IsARM64: () => IsARM64, + IsDarkMode: () => IsDarkMode, + IsLinux: () => IsLinux, + IsMac: () => IsMac, + IsWindows: () => IsWindows, + invoke: () => invoke + }); + var call4 = newRuntimeCallerWithID(objectNames.System, ""); + var systemIsDarkMode = 0; + var environment = 1; + function IsDarkMode() { + return call4(systemIsDarkMode); + } + async function Capabilities() { + let response = fetch("/wails/capabilities"); + return response.json(); + } + function Environment() { + return call4(environment); + } + var invoke = null; + var environmentCache = null; + Environment().then((result) => { + environmentCache = result; + invoke = IsWindows() ? window.chrome.webview.postMessage : window.webkit.messageHandlers.external.postMessage; + }).catch((error) => { + console.error(`Error getting Environment: ${error}`); + }); + function IsWindows() { + return environmentCache.OS === "windows"; + } + function IsLinux() { + return environmentCache.OS === "linux"; + } + function IsMac() { + return environmentCache.OS === "darwin"; + } + function IsAMD64() { + return environmentCache.Arch === "amd64"; + } + function IsARM() { + return environmentCache.Arch === "arm"; + } + function IsARM64() { + return environmentCache.Arch === "arm64"; + } + + // desktop/@wailsio/runtime/browser.js + var browser_exports = {}; + __export(browser_exports, { + OpenURL: () => OpenURL + }); + var call5 = newRuntimeCallerWithID(objectNames.Browser, ""); + var BrowserOpenURL = 0; + function OpenURL(url) { + return call5(BrowserOpenURL, { url }); + } + + // desktop/@wailsio/runtime/window.js + var center = 0; + var setTitle = 1; + var fullscreen = 2; + var unFullscreen = 3; + var setSize = 4; + var size = 5; + var setMaxSize = 6; + var setMinSize = 7; + var setAlwaysOnTop = 8; + var setRelativePosition = 9; + var relativePosition = 10; + var screen = 11; + var hide = 12; + var maximise = 13; + var unMaximise = 14; + var toggleMaximise = 15; + var minimise = 16; + var unMinimise = 17; + var restore = 18; + var show = 19; + var close = 20; + var setBackgroundColour = 21; + var setResizable = 22; + var width = 23; + var height = 24; + var zoomIn = 25; + var zoomOut = 26; + var zoomReset = 27; + var getZoomLevel = 28; + var setZoomLevel = 29; + var thisWindow = newRuntimeCallerWithID(objectNames.Window, ""); + function createWindow(call10) { + return { + Get: (windowName) => createWindow(newRuntimeCallerWithID(objectNames.Window, windowName)), + Center: () => call10(center), + SetTitle: (title) => call10(setTitle, { title }), + Fullscreen: () => call10(fullscreen), + UnFullscreen: () => call10(unFullscreen), + SetSize: (width2, height2) => call10(setSize, { width: width2, height: height2 }), + Size: () => call10(size), + SetMaxSize: (width2, height2) => call10(setMaxSize, { width: width2, height: height2 }), + SetMinSize: (width2, height2) => call10(setMinSize, { width: width2, height: height2 }), + SetAlwaysOnTop: (onTop) => call10(setAlwaysOnTop, { alwaysOnTop: onTop }), + SetRelativePosition: (x, y) => call10(setRelativePosition, { x, y }), + RelativePosition: () => call10(relativePosition), + Screen: () => call10(screen), + Hide: () => call10(hide), + Maximise: () => call10(maximise), + UnMaximise: () => call10(unMaximise), + ToggleMaximise: () => call10(toggleMaximise), + Minimise: () => call10(minimise), + UnMinimise: () => call10(unMinimise), + Restore: () => call10(restore), + Show: () => call10(show), + Close: () => call10(close), + SetBackgroundColour: (r, g, b, a) => call10(setBackgroundColour, { r, g, b, a }), + SetResizable: (resizable2) => call10(setResizable, { resizable: resizable2 }), + Width: () => call10(width), + Height: () => call10(height), + ZoomIn: () => call10(zoomIn), + ZoomOut: () => call10(zoomOut), + ZoomReset: () => call10(zoomReset), + GetZoomLevel: () => call10(getZoomLevel), + SetZoomLevel: (zoomLevel) => call10(setZoomLevel, { zoomLevel }) + }; + } + function Get(windowName) { + return createWindow(newRuntimeCallerWithID(objectNames.Window, windowName)); + } + function WindowMethods(targetWindow) { + let result = /* @__PURE__ */ new Map(); + for (let method in targetWindow) { + if (typeof targetWindow[method] === "function") { + result.set(method, targetWindow[method]); + } + } + return result; + } + var window_default = { + ...Get("") + }; + + // desktop/@wailsio/runtime/calls.js + var CallBinding = 0; + var call6 = newRuntimeCallerWithID(objectNames.Call, ""); + var callResponses = /* @__PURE__ */ new Map(); + window._wails = window._wails || {}; + window._wails.callCallback = resultHandler; + window._wails.callErrorCallback = errorHandler; + function generateID() { + let result; + do { + result = nanoid(); + } while (callResponses.has(result)); + return result; + } + function resultHandler(id, data, isJSON) { + const promiseHandler = getAndDeleteResponse(id); + if (promiseHandler) { + promiseHandler.resolve(isJSON ? JSON.parse(data) : data); + } + } + function errorHandler(id, message) { + const promiseHandler = getAndDeleteResponse(id); + if (promiseHandler) { + promiseHandler.reject(message); + } + } + function getAndDeleteResponse(id) { + const response = callResponses.get(id); + callResponses.delete(id); + return response; + } + function callBinding(type, options = {}) { + return new Promise((resolve, reject) => { + const id = generateID(); + options["call-id"] = id; + callResponses.set(id, { resolve, reject }); + call6(type, options).catch((error) => { + reject(error); + callResponses.delete(id); + }); + }); + } + function Call(options) { + return callBinding(CallBinding, options); + } + function ByName(name, ...args) { + if (typeof name !== "string" || name.split(".").length !== 3) { + throw new Error("CallByName requires a string in the format 'package.struct.method'"); + } + let [packageName, structName, methodName] = name.split("."); + return callBinding(CallBinding, { + packageName, + structName, + methodName, + args + }); + } + function ByID(methodID, ...args) { + return callBinding(CallBinding, { + methodID, + args + }); + } + function Plugin(pluginName, methodName, ...args) { + return callBinding(CallBinding, { + packageName: "wails-plugins", + structName: pluginName, + methodName, + args + }); + } + + // desktop/@wailsio/runtime/events.js + var call7 = newRuntimeCallerWithID(objectNames.Events, ""); + var EmitMethod = 0; + var eventListeners = /* @__PURE__ */ new Map(); + var Listener = class { + constructor(eventName, callback, maxCallbacks) { + this.eventName = eventName; + this.maxCallbacks = maxCallbacks || -1; + this.Callback = (data) => { + callback(data); + if (this.maxCallbacks === -1) + return false; + this.maxCallbacks -= 1; + return this.maxCallbacks === 0; + }; + } + }; + var WailsEvent = class { + constructor(name, data = null) { + this.name = name; + this.data = data; + } + }; + window._wails = window._wails || {}; + window._wails.dispatchWailsEvent = dispatchWailsEvent; + function dispatchWailsEvent(event) { + let listeners = eventListeners.get(event.name); + if (listeners) { + let toRemove = listeners.filter((listener) => { + let remove = listener.Callback(event); + if (remove) + return true; + }); + if (toRemove.length > 0) { + listeners = listeners.filter((l) => !toRemove.includes(l)); + if (listeners.length === 0) + eventListeners.delete(event.name); + else + eventListeners.set(event.name, listeners); + } + } + } + function OnMultiple(eventName, callback, maxCallbacks) { + let listeners = eventListeners.get(eventName) || []; + const thisListener = new Listener(eventName, callback, maxCallbacks); + listeners.push(thisListener); + eventListeners.set(eventName, listeners); + return () => listenerOff(thisListener); + } + function On(eventName, callback) { + return OnMultiple(eventName, callback, -1); + } + function Once(eventName, callback) { + return OnMultiple(eventName, callback, 1); + } + function listenerOff(listener) { + const eventName = listener.eventName; + let listeners = eventListeners.get(eventName).filter((l) => l !== listener); + if (listeners.length === 0) + eventListeners.delete(eventName); + else + eventListeners.set(eventName, listeners); + } + function Off(eventName, ...additionalEventNames) { + let eventsToRemove = [eventName, ...additionalEventNames]; + eventsToRemove.forEach((eventName2) => eventListeners.delete(eventName2)); + } + function OffAll() { + eventListeners.clear(); + } + function Emit(event) { + return call7(EmitMethod, event); + } + + // desktop/@wailsio/runtime/dialogs.js + var DialogInfo = 0; + var DialogWarning = 1; + var DialogError = 2; + var DialogQuestion = 3; + var DialogOpenFile = 4; + var DialogSaveFile = 5; + var call8 = newRuntimeCallerWithID(objectNames.Dialog, ""); + var dialogResponses = /* @__PURE__ */ new Map(); + function generateID2() { + let result; + do { + result = nanoid(); + } while (dialogResponses.has(result)); + return result; + } + function dialog(type, options = {}) { + const id = generateID2(); + options["dialog-id"] = id; + return new Promise((resolve, reject) => { + dialogResponses.set(id, { resolve, reject }); + call8(type, options).catch((error) => { + reject(error); + dialogResponses.delete(id); + }); + }); + } + function dialogCallback(id, data, isJSON) { + let p = dialogResponses.get(id); + if (p) { + if (isJSON) { + p.resolve(JSON.parse(data)); + } else { + p.resolve(data); + } + dialogResponses.delete(id); + } + } + function dialogErrorCallback(id, message) { + let p = dialogResponses.get(id); + if (p) { + p.reject(message); + dialogResponses.delete(id); + } + } + var Info = (options) => dialog(DialogInfo, options); + var Warning = (options) => dialog(DialogWarning, options); + var Error2 = (options) => dialog(DialogError, options); + var Question = (options) => dialog(DialogQuestion, options); + var OpenFile = (options) => dialog(DialogOpenFile, options); + var SaveFile = (options) => dialog(DialogSaveFile, options); + + // desktop/@wailsio/runtime/contextmenu.js + var call9 = newRuntimeCallerWithID(objectNames.ContextMenu, ""); + var ContextMenuOpen = 0; + function openContextMenu(id, x, y, data) { + void call9(ContextMenuOpen, { id, x, y, data }); + } + function setupContextMenus() { + window.addEventListener("contextmenu", contextMenuHandler); + } + function contextMenuHandler(event) { + let element = event.target; + let customContextMenu = window.getComputedStyle(element).getPropertyValue("--custom-contextmenu"); + customContextMenu = customContextMenu ? customContextMenu.trim() : ""; + if (customContextMenu) { + event.preventDefault(); + let customContextMenuData = window.getComputedStyle(element).getPropertyValue("--custom-contextmenu-data"); + openContextMenu(customContextMenu, event.clientX, event.clientY, customContextMenuData); + return; + } + processDefaultContextMenu(event); + } + function processDefaultContextMenu(event) { + if (true) { + return; + } + const element = event.target; + const computedStyle = window.getComputedStyle(element); + const defaultContextMenuAction = computedStyle.getPropertyValue("--default-contextmenu").trim(); + switch (defaultContextMenuAction) { + case "show": + return; + case "hide": + event.preventDefault(); + return; + default: + if (element.isContentEditable) { + return; + } + const selection = window.getSelection(); + const hasSelection = selection.toString().length > 0; + if (hasSelection) { + for (let i = 0; i < selection.rangeCount; i++) { + const range = selection.getRangeAt(i); + const rects = range.getClientRects(); + for (let j = 0; j < rects.length; j++) { + const rect = rects[j]; + if (document.elementFromPoint(rect.left, rect.top) === element) { + return; + } + } + } + } + if (element.tagName === "INPUT" || element.tagName === "TEXTAREA") { + if (hasSelection || !element.readOnly && !element.disabled) { + return; + } + } + event.preventDefault(); + } + } + + // desktop/@wailsio/runtime/wml.js + function sendEvent(eventName, data = null) { + let event = new WailsEvent(eventName, data); + Emit(event); + } + function addWMLEventListeners() { + const elements = document.querySelectorAll("[wml-event]"); + elements.forEach(function(element) { + const eventType = element.getAttribute("wml-event"); + const confirm = element.getAttribute("wml-confirm"); + const trigger = element.getAttribute("wml-trigger") || "click"; + let callback = function() { + if (confirm) { + Question({ Title: "Confirm", Message: confirm, Detached: false, Buttons: [{ Label: "Yes" }, { Label: "No", IsDefault: true }] }).then(function(result) { + if (result !== "No") { + sendEvent(eventType); + } + }); + return; + } + sendEvent(eventType); + }; + element.removeEventListener(trigger, callback); + element.addEventListener(trigger, callback); + }); + } + function callWindowMethod(method) { + let windowName = ""; + let targetWindow = Get(""); + let methodMap = WindowMethods(targetWindow); + if (!methodMap.has(method)) { + console.log("Window method " + method + " not found"); + } + methodMap.get(method)(); + } + function addWMLWindowListeners() { + const elements = document.querySelectorAll("[wml-window]"); + elements.forEach(function(element) { + const windowMethod = element.getAttribute("wml-window"); + const confirm = element.getAttribute("wml-confirm"); + const trigger = element.getAttribute("wml-trigger") || "click"; + let callback = function() { + if (confirm) { + Question({ Title: "Confirm", Message: confirm, Buttons: [{ Label: "Yes" }, { Label: "No", IsDefault: true }] }).then(function(result) { + if (result !== "No") { + callWindowMethod(windowMethod); + } + }); + return; + } + callWindowMethod(windowMethod); + }; + element.removeEventListener(trigger, callback); + element.addEventListener(trigger, callback); + }); + } + function addWMLOpenBrowserListener() { + const elements = document.querySelectorAll("[wml-openurl]"); + elements.forEach(function(element) { + const url = element.getAttribute("wml-openurl"); + const confirm = element.getAttribute("wml-confirm"); + const trigger = element.getAttribute("wml-trigger") || "click"; + let callback = function() { + if (confirm) { + Question({ Title: "Confirm", Message: confirm, Buttons: [{ Label: "Yes" }, { Label: "No", IsDefault: true }] }).then(function(result) { + if (result !== "No") { + void wails.Browser.OpenURL(url); + } + }); + return; + } + void wails.Browser.OpenURL(url); + }; + element.removeEventListener(trigger, callback); + element.addEventListener(trigger, callback); + }); + } + function reloadWML() { + console.log("Reloading WML"); + addWMLEventListeners(); + addWMLWindowListeners(); + addWMLOpenBrowserListener(); + } + + // desktop/@wailsio/runtime/flags.js + var flags = /* @__PURE__ */ new Map(); + function convertToMap(obj) { + const map = /* @__PURE__ */ new Map(); + for (const [key, value] of Object.entries(obj)) { + if (typeof value === "object" && value !== null) { + map.set(key, convertToMap(value)); + } else { + map.set(key, value); + } + } + return map; + } + fetch("/wails/flags").then((response) => { + response.json().then((data) => { + flags = convertToMap(data); + }); + }); + function getValueFromMap(keyString) { + const keys = keyString.split("."); + let value = flags; + for (const key of keys) { + if (value instanceof Map) { + value = value.get(key); + } else { + value = value[key]; + } + if (value === void 0) { + break; + } + } + return value; + } + function GetFlag(keyString) { + return getValueFromMap(keyString); + } + + // desktop/@wailsio/runtime/drag.js + var shouldDrag = false; + var resizeEdge = null; + var resizable = false; + var defaultCursor = "auto"; + window._wails = window._wails || {}; + window._wails.setResizable = setResizable2; + window._wails.endDrag = endDrag; + function dragTest(e) { + let val = window.getComputedStyle(e.target).getPropertyValue("--webkit-app-region"); + if (val && val.trim() !== "drag" || e.buttons !== 1) { + return false; + } + return e.detail === 1; + } + function setupDrag() { + window.addEventListener("mousedown", onMouseDown); + window.addEventListener("mousemove", onMouseMove); + window.addEventListener("mouseup", onMouseUp); + } + function setResizable2(value) { + resizable = value; + } + function endDrag() { + document.body.style.cursor = "default"; + shouldDrag = false; + } + function testResize() { + if (resizeEdge) { + invoke(`resize:${resizeEdge}`); + return true; + } + return false; + } + function onMouseDown(e) { + if (IsWindows() && testResize() || dragTest(e)) { + shouldDrag = !!isValidDrag(e); + } + } + function isValidDrag(e) { + return !(e.offsetX > e.target.clientWidth || e.offsetY > e.target.clientHeight); + } + function onMouseUp(e) { + let mousePressed = e.buttons !== void 0 ? e.buttons : e.which; + if (mousePressed > 0) { + endDrag(); + } + } + function setResize(cursor = defaultCursor) { + document.documentElement.style.cursor = cursor; + resizeEdge = cursor; + } + function onMouseMove(e) { + shouldDrag = checkDrag(e); + if (IsWindows() && resizable) { + handleResize(e); + } + } + function checkDrag(e) { + let mousePressed = e.buttons !== void 0 ? e.buttons : e.which; + if (shouldDrag && mousePressed > 0) { + invoke("drag"); + return false; + } + return shouldDrag; + } + function handleResize(e) { + let resizeHandleHeight = GetFlag("system.resizeHandleHeight") || 5; + let resizeHandleWidth = GetFlag("system.resizeHandleWidth") || 5; + let cornerExtra = GetFlag("resizeCornerExtra") || 10; + let rightBorder = window.outerWidth - e.clientX < resizeHandleWidth; + let leftBorder = e.clientX < resizeHandleWidth; + let topBorder = e.clientY < resizeHandleHeight; + let bottomBorder = window.outerHeight - e.clientY < resizeHandleHeight; + let rightCorner = window.outerWidth - e.clientX < resizeHandleWidth + cornerExtra; + let leftCorner = e.clientX < resizeHandleWidth + cornerExtra; + let topCorner = e.clientY < resizeHandleHeight + cornerExtra; + let bottomCorner = window.outerHeight - e.clientY < resizeHandleHeight + cornerExtra; + if (!leftBorder && !rightBorder && !topBorder && !bottomBorder && resizeEdge !== void 0) { + setResize(); + } else if (rightCorner && bottomCorner) + setResize("se-resize"); + else if (leftCorner && bottomCorner) + setResize("sw-resize"); + else if (leftCorner && topCorner) + setResize("nw-resize"); + else if (topCorner && rightCorner) + setResize("ne-resize"); + else if (leftBorder) + setResize("w-resize"); + else if (topBorder) + setResize("n-resize"); + else if (bottomBorder) + setResize("s-resize"); + else if (rightBorder) + setResize("e-resize"); + } + + // desktop/main.js + window.wails = { + ...newRuntime(null), + clientId + }; + window._wails = { + dialogCallback, + dialogErrorCallback, + dispatchWailsEvent, + callErrorHandler: errorHandler, + callResultHandler: resultHandler, + endDrag, + setResizable: setResizable2 + }; + function newRuntime(windowName) { + return { + Clipboard: { + ...clipboard_exports + }, + Application: { + ...application_exports + }, + System: system_exports, + Screens: screens_exports, + Browser: browser_exports, + Call: { + Call, + ByID, + ByName, + Plugin + }, + WML: { + Reload: reloadWML + }, + Dialog: { + Info, + Warning, + Error: Error2, + Question, + OpenFile, + SaveFile + }, + Events: { + Emit, + On, + Once, + OnMultiple, + Off, + OffAll + }, + Window: { + ...Get("") + } + }; + } + setupContextMenus(); + setupDrag(); + document.addEventListener("DOMContentLoaded", function() { + reloadWML(); + }); +})(); +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL2NsaXBib2FyZC5qcyIsICJub2RlX21vZHVsZXMvbmFub2lkL25vbi1zZWN1cmUvaW5kZXguanMiLCAiZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL3J1bnRpbWUuanMiLCAiZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL2FwcGxpY2F0aW9uLmpzIiwgImRlc2t0b3AvQHdhaWxzaW8vcnVudGltZS9zY3JlZW5zLmpzIiwgImRlc2t0b3AvQHdhaWxzaW8vcnVudGltZS9zeXN0ZW0uanMiLCAiZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL2Jyb3dzZXIuanMiLCAiZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL3dpbmRvdy5qcyIsICJkZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvY2FsbHMuanMiLCAiZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL2V2ZW50cy5qcyIsICJkZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvZGlhbG9ncy5qcyIsICJkZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvY29udGV4dG1lbnUuanMiLCAiZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL3dtbC5qcyIsICJkZXNrdG9wL0B3YWlsc2lvL3J1bnRpbWUvZmxhZ3MuanMiLCAiZGVza3RvcC9Ad2FpbHNpby9ydW50aW1lL2RyYWcuanMiLCAiZGVza3RvcC9tYWluLmpzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcblxyXG5pbXBvcnQge25ld1J1bnRpbWVDYWxsZXJXaXRoSUQsIG9iamVjdE5hbWVzfSBmcm9tIFwiLi9ydW50aW1lXCI7XHJcblxyXG5jb25zdCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5DbGlwYm9hcmQsICcnKTtcclxuY29uc3QgQ2xpcGJvYXJkU2V0VGV4dCA9IDA7XHJcbmNvbnN0IENsaXBib2FyZFRleHQgPSAxO1xyXG5cclxuLyoqXHJcbiAqIFNldHMgdGhlIHRleHQgdG8gdGhlIENsaXBib2FyZC5cclxuICpcclxuICogQHBhcmFtIHtzdHJpbmd9IHRleHQgLSBUaGUgdGV4dCB0byBiZSBzZXQgdG8gdGhlIENsaXBib2FyZC5cclxuICogQHJldHVybiB7UHJvbWlzZX0gLSBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBvcGVyYXRpb24gaXMgc3VjY2Vzc2Z1bC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBTZXRUZXh0KHRleHQpIHtcclxuICAgIHJldHVybiBjYWxsKENsaXBib2FyZFNldFRleHQsIHt0ZXh0fSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgdGhlIENsaXBib2FyZCB0ZXh0XHJcbiAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZz59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIHRleHQgZnJvbSB0aGUgQ2xpcGJvYXJkLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIFRleHQoKSB7XHJcbiAgICByZXR1cm4gY2FsbChDbGlwYm9hcmRUZXh0KTtcclxufVxyXG4iLCAibGV0IHVybEFscGhhYmV0ID1cbiAgJ3VzZWFuZG9tLTI2VDE5ODM0MFBYNzVweEpBQ0tWRVJZTUlOREJVU0hXT0xGX0dRWmJmZ2hqa2xxdnd5enJpY3QnXG5leHBvcnQgbGV0IGN1c3RvbUFscGhhYmV0ID0gKGFscGhhYmV0LCBkZWZhdWx0U2l6ZSA9IDIxKSA9PiB7XG4gIHJldHVybiAoc2l6ZSA9IGRlZmF1bHRTaXplKSA9PiB7XG4gICAgbGV0IGlkID0gJydcbiAgICBsZXQgaSA9IHNpemVcbiAgICB3aGlsZSAoaS0tKSB7XG4gICAgICBpZCArPSBhbHBoYWJldFsoTWF0aC5yYW5kb20oKSAqIGFscGhhYmV0Lmxlbmd0aCkgfCAwXVxuICAgIH1cbiAgICByZXR1cm4gaWRcbiAgfVxufVxuZXhwb3J0IGxldCBuYW5vaWQgPSAoc2l6ZSA9IDIxKSA9PiB7XG4gIGxldCBpZCA9ICcnXG4gIGxldCBpID0gc2l6ZVxuICB3aGlsZSAoaS0tKSB7XG4gICAgaWQgKz0gdXJsQWxwaGFiZXRbKE1hdGgucmFuZG9tKCkgKiA2NCkgfCAwXVxuICB9XG4gIHJldHVybiBpZFxufVxuIiwgIi8qXHJcbiBfICAgICBfXyAgICAgXyBfX1xyXG58IHwgIC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuaW1wb3J0IHsgbmFub2lkIH0gZnJvbSAnbmFub2lkL25vbi1zZWN1cmUnO1xyXG5cclxuY29uc3QgcnVudGltZVVSTCA9IHdpbmRvdy5sb2NhdGlvbi5vcmlnaW4gKyBcIi93YWlscy9ydW50aW1lXCI7XHJcblxyXG4vLyBPYmplY3QgTmFtZXNcclxuZXhwb3J0IGNvbnN0IG9iamVjdE5hbWVzID0ge1xyXG4gICAgQ2FsbDogMCxcclxuICAgIENsaXBib2FyZDogMSxcclxuICAgIEFwcGxpY2F0aW9uOiAyLFxyXG4gICAgRXZlbnRzOiAzLFxyXG4gICAgQ29udGV4dE1lbnU6IDQsXHJcbiAgICBEaWFsb2c6IDUsXHJcbiAgICBXaW5kb3c6IDYsXHJcbiAgICBTY3JlZW5zOiA3LFxyXG4gICAgU3lzdGVtOiA4LFxyXG4gICAgQnJvd3NlcjogOSxcclxufVxyXG5leHBvcnQgbGV0IGNsaWVudElkID0gbmFub2lkKCk7XHJcblxyXG4vKipcclxuICogQ3JlYXRlcyBhIHJ1bnRpbWUgY2FsbGVyIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBhIHNwZWNpZmllZCBtZXRob2Qgb24gYSBnaXZlbiBvYmplY3Qgd2l0aGluIGEgc3BlY2lmaWVkIHdpbmRvdyBjb250ZXh0LlxyXG4gKlxyXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IC0gVGhlIG9iamVjdCBvbiB3aGljaCB0aGUgbWV0aG9kIGlzIHRvIGJlIGludm9rZWQuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSB3aW5kb3dOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHdpbmRvdyBjb250ZXh0IGluIHdoaWNoIHRoZSBtZXRob2Qgc2hvdWxkIGJlIGNhbGxlZC5cclxuICogQHJldHVybnMge0Z1bmN0aW9ufSBBIHJ1bnRpbWUgY2FsbGVyIGZ1bmN0aW9uIHRoYXQgdGFrZXMgdGhlIG1ldGhvZCBuYW1lIGFuZCBvcHRpb25hbGx5IGFyZ3VtZW50cyBhbmQgaW52b2tlcyB0aGUgbWV0aG9kIHdpdGhpbiB0aGUgc3BlY2lmaWVkIHdpbmRvdyBjb250ZXh0LlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIG5ld1J1bnRpbWVDYWxsZXIob2JqZWN0LCB3aW5kb3dOYW1lKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKG1ldGhvZCwgYXJncz1udWxsKSB7XHJcbiAgICAgICAgcmV0dXJuIHJ1bnRpbWVDYWxsKG9iamVjdCArIFwiLlwiICsgbWV0aG9kLCB3aW5kb3dOYW1lLCBhcmdzKTtcclxuICAgIH07XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDcmVhdGVzIGEgbmV3IHJ1bnRpbWUgY2FsbGVyIHdpdGggc3BlY2lmaWVkIElELlxyXG4gKlxyXG4gKiBAcGFyYW0ge29iamVjdH0gb2JqZWN0IC0gVGhlIG9iamVjdCB0byBpbnZva2UgdGhlIG1ldGhvZCBvbi5cclxuICogQHBhcmFtIHtzdHJpbmd9IHdpbmRvd05hbWUgLSBUaGUgbmFtZSBvZiB0aGUgd2luZG93LlxyXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gLSBUaGUgbmV3IHJ1bnRpbWUgY2FsbGVyIGZ1bmN0aW9uLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIG5ld1J1bnRpbWVDYWxsZXJXaXRoSUQob2JqZWN0LCB3aW5kb3dOYW1lKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKG1ldGhvZCwgYXJncz1udWxsKSB7XHJcbiAgICAgICAgcmV0dXJuIHJ1bnRpbWVDYWxsV2l0aElEKG9iamVjdCwgbWV0aG9kLCB3aW5kb3dOYW1lLCBhcmdzKTtcclxuICAgIH07XHJcbn1cclxuXHJcblxyXG5mdW5jdGlvbiBydW50aW1lQ2FsbChtZXRob2QsIHdpbmRvd05hbWUsIGFyZ3MpIHtcclxuICAgIGxldCB1cmwgPSBuZXcgVVJMKHJ1bnRpbWVVUkwpO1xyXG4gICAgaWYoIG1ldGhvZCApIHtcclxuICAgICAgICB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChcIm1ldGhvZFwiLCBtZXRob2QpO1xyXG4gICAgfVxyXG4gICAgbGV0IGZldGNoT3B0aW9ucyA9IHtcclxuICAgICAgICBoZWFkZXJzOiB7fSxcclxuICAgIH07XHJcbiAgICBpZiAod2luZG93TmFtZSkge1xyXG4gICAgICAgIGZldGNoT3B0aW9ucy5oZWFkZXJzW1wieC13YWlscy13aW5kb3ctbmFtZVwiXSA9IHdpbmRvd05hbWU7XHJcbiAgICB9XHJcbiAgICBpZiAoYXJncykge1xyXG4gICAgICAgIHVybC5zZWFyY2hQYXJhbXMuYXBwZW5kKFwiYXJnc1wiLCBKU09OLnN0cmluZ2lmeShhcmdzKSk7XHJcbiAgICB9XHJcbiAgICBmZXRjaE9wdGlvbnMuaGVhZGVyc1tcIngtd2FpbHMtY2xpZW50LWlkXCJdID0gY2xpZW50SWQ7XHJcblxyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICBmZXRjaCh1cmwsIGZldGNoT3B0aW9ucylcclxuICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgY29udGVudCB0eXBlXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiQ29udGVudC1UeXBlXCIpICYmIHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiQ29udGVudC1UeXBlXCIpLmluZGV4T2YoXCJhcHBsaWNhdGlvbi9qc29uXCIpICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZS50ZXh0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKHJlc3BvbnNlLnN0YXR1c1RleHQpKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLnRoZW4oZGF0YSA9PiByZXNvbHZlKGRhdGEpKVxyXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gcnVudGltZUNhbGxXaXRoSUQob2JqZWN0SUQsIG1ldGhvZCwgd2luZG93TmFtZSwgYXJncykge1xyXG4gICAgbGV0IHVybCA9IG5ldyBVUkwocnVudGltZVVSTCk7XHJcbiAgICB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChcIm9iamVjdFwiLCBvYmplY3RJRCk7XHJcbiAgICB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChcIm1ldGhvZFwiLCBtZXRob2QpO1xyXG4gICAgbGV0IGZldGNoT3B0aW9ucyA9IHtcclxuICAgICAgICBoZWFkZXJzOiB7fSxcclxuICAgIH07XHJcbiAgICBpZiAod2luZG93TmFtZSkge1xyXG4gICAgICAgIGZldGNoT3B0aW9ucy5oZWFkZXJzW1wieC13YWlscy13aW5kb3ctbmFtZVwiXSA9IHdpbmRvd05hbWU7XHJcbiAgICB9XHJcbiAgICBpZiAoYXJncykge1xyXG4gICAgICAgIHVybC5zZWFyY2hQYXJhbXMuYXBwZW5kKFwiYXJnc1wiLCBKU09OLnN0cmluZ2lmeShhcmdzKSk7XHJcbiAgICB9XHJcbiAgICBmZXRjaE9wdGlvbnMuaGVhZGVyc1tcIngtd2FpbHMtY2xpZW50LWlkXCJdID0gY2xpZW50SWQ7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgIGZldGNoKHVybCwgZmV0Y2hPcHRpb25zKVxyXG4gICAgICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2Uub2spIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBjaGVjayBjb250ZW50IHR5cGVcclxuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UuaGVhZGVycy5nZXQoXCJDb250ZW50LVR5cGVcIikgJiYgcmVzcG9uc2UuaGVhZGVycy5nZXQoXCJDb250ZW50LVR5cGVcIikuaW5kZXhPZihcImFwcGxpY2F0aW9uL2pzb25cIikgIT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3BvbnNlLnRleHQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZWplY3QoRXJyb3IocmVzcG9uc2Uuc3RhdHVzVGV4dCkpO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAudGhlbihkYXRhID0+IHJlc29sdmUoZGF0YSkpXHJcbiAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiByZWplY3QoZXJyb3IpKTtcclxuICAgIH0pO1xyXG59XHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcblxyXG5pbXBvcnQgeyBuZXdSdW50aW1lQ2FsbGVyV2l0aElELCBvYmplY3ROYW1lcyB9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuY29uc3QgY2FsbCA9IG5ld1J1bnRpbWVDYWxsZXJXaXRoSUQob2JqZWN0TmFtZXMuQXBwbGljYXRpb24pO1xyXG5cclxuY29uc3QgSGlkZU1ldGhvZCA9IDA7XHJcbmNvbnN0IFNob3dNZXRob2QgPSAxO1xyXG5jb25zdCBRdWl0TWV0aG9kID0gMjtcclxuXHJcbi8qKlxyXG4gKiBIaWRlcyBhIGNlcnRhaW4gbWV0aG9kIGJ5IGNhbGxpbmcgdGhlIEhpZGVNZXRob2QgZnVuY3Rpb24uXHJcbiAqXHJcbiAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59XHJcbiAqXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gSGlkZSgpIHtcclxuICAgIHJldHVybiBjYWxsKEhpZGVNZXRob2QpO1xyXG59XHJcblxyXG4vKipcclxuICogQ2FsbHMgdGhlIFNob3dNZXRob2QgYW5kIHJldHVybnMgdGhlIHJlc3VsdC5cclxuICpcclxuICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn1cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBTaG93KCkge1xyXG4gICAgcmV0dXJuIGNhbGwoU2hvd01ldGhvZCk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDYWxscyB0aGUgUXVpdE1ldGhvZCB0byB0ZXJtaW5hdGUgdGhlIHByb2dyYW0uXHJcbiAqXHJcbiAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gUXVpdCgpIHtcclxuICAgIHJldHVybiBjYWxsKFF1aXRNZXRob2QpO1xyXG59XHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcblxyXG4vKipcclxuICogQHR5cGVkZWYge2ltcG9ydChcIi4vYXBpL3R5cGVzXCIpLlNjcmVlbn0gU2NyZWVuXHJcbiAqL1xyXG5cclxuaW1wb3J0IHtuZXdSdW50aW1lQ2FsbGVyV2l0aElELCBvYmplY3ROYW1lc30gZnJvbSBcIi4vcnVudGltZVwiO1xyXG5jb25zdCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5TY3JlZW5zLCAnJyk7XHJcblxyXG5jb25zdCBnZXRBbGwgPSAwO1xyXG5jb25zdCBnZXRQcmltYXJ5ID0gMTtcclxuY29uc3QgZ2V0Q3VycmVudCA9IDI7XHJcblxyXG4vKipcclxuICogR2V0cyBhbGwgc2NyZWVucy5cclxuICogQHJldHVybnMge1Byb21pc2U8U2NyZWVuW10+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBvZiBTY3JlZW4gb2JqZWN0cy5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBHZXRBbGwoKSB7XHJcbiAgICByZXR1cm4gY2FsbChnZXRBbGwpO1xyXG59XHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBwcmltYXJ5IHNjcmVlbi5cclxuICogQHJldHVybnMge1Byb21pc2U8U2NyZWVuPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHByaW1hcnkgc2NyZWVuLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIEdldFByaW1hcnkoKSB7XHJcbiAgICByZXR1cm4gY2FsbChnZXRQcmltYXJ5KTtcclxufVxyXG4vKipcclxuICogR2V0cyB0aGUgY3VycmVudCBhY3RpdmUgc2NyZWVuLlxyXG4gKlxyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxTY3JlZW4+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBjdXJyZW50IGFjdGl2ZSBzY3JlZW4uXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gR2V0Q3VycmVudCgpIHtcclxuICAgIHJldHVybiBjYWxsKGdldEN1cnJlbnQpO1xyXG59IiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxubGV0IGNhbGwgPSBuZXdSdW50aW1lQ2FsbGVyV2l0aElEKG9iamVjdE5hbWVzLlN5c3RlbSwgJycpO1xyXG5jb25zdCBzeXN0ZW1Jc0RhcmtNb2RlID0gMDtcclxuY29uc3QgZW52aXJvbm1lbnQgPSAxO1xyXG5cclxuLyoqXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBSZXRyaWV2ZXMgdGhlIHN5c3RlbSBkYXJrIG1vZGUgc3RhdHVzLlxyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gLSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhIGJvb2xlYW4gdmFsdWUgaW5kaWNhdGluZyBpZiB0aGUgc3lzdGVtIGlzIGluIGRhcmsgbW9kZS5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBJc0RhcmtNb2RlKCkge1xyXG4gICAgcmV0dXJuIGNhbGwoc3lzdGVtSXNEYXJrTW9kZSk7XHJcbn1cclxuXHJcblxyXG4vKipcclxuICogRmV0Y2hlcyB0aGUgY2FwYWJpbGl0aWVzIG9mIHRoZSBhcHBsaWNhdGlvbiBmcm9tIHRoZSBzZXJ2ZXIuXHJcbiAqXHJcbiAqIEBhc3luY1xyXG4gKiBAZnVuY3Rpb24gQ2FwYWJpbGl0aWVzXHJcbiAqIEByZXR1cm5zIHtQcm9taXNlPE9iamVjdD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIG9iamVjdCBjb250YWluaW5nIHRoZSBjYXBhYmlsaXRpZXMuXHJcbiAqL1xyXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gQ2FwYWJpbGl0aWVzKCkge1xyXG4gICAgbGV0IHJlc3BvbnNlID0gZmV0Y2goXCIvd2FpbHMvY2FwYWJpbGl0aWVzXCIpO1xyXG4gICAgcmV0dXJuIHJlc3BvbnNlLmpzb24oKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEB0eXBlZGVmIHtvYmplY3R9IEVudmlyb25tZW50SW5mb1xyXG4gKiBAcHJvcGVydHkge3N0cmluZ30gT1MgLSBUaGUgb3BlcmF0aW5nIHN5c3RlbSBpbiB1c2UuXHJcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBBcmNoIC0gVGhlIGFyY2hpdGVjdHVyZSBvZiB0aGUgc3lzdGVtLlxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBAZnVuY3Rpb25cclxuICogUmV0cmlldmVzIGVudmlyb25tZW50IGRldGFpbHMuXHJcbiAqIEByZXR1cm5zIHtQcm9taXNlPEVudmlyb25tZW50SW5mbz59IC0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gb2JqZWN0IGNvbnRhaW5pbmcgT1MgYW5kIHN5c3RlbSBhcmNoaXRlY3R1cmUuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gRW52aXJvbm1lbnQoKSB7XHJcbiAgICByZXR1cm4gY2FsbChlbnZpcm9ubWVudCk7XHJcbn1cclxuXHJcbmV4cG9ydCBsZXQgaW52b2tlID0gbnVsbDtcclxubGV0IGVudmlyb25tZW50Q2FjaGUgPSBudWxsO1xyXG5cclxuRW52aXJvbm1lbnQoKVxyXG4gICAgLnRoZW4ocmVzdWx0ID0+IHtcclxuICAgICAgICBlbnZpcm9ubWVudENhY2hlID0gcmVzdWx0O1xyXG4gICAgICAgIGludm9rZSA9IElzV2luZG93cygpID8gd2luZG93LmNocm9tZS53ZWJ2aWV3LnBvc3RNZXNzYWdlIDogd2luZG93LndlYmtpdC5tZXNzYWdlSGFuZGxlcnMuZXh0ZXJuYWwucG9zdE1lc3NhZ2U7XHJcbiAgICB9KVxyXG4gICAgLmNhdGNoKGVycm9yID0+IHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKGBFcnJvciBnZXR0aW5nIEVudmlyb25tZW50OiAke2Vycm9yfWApO1xyXG4gICAgfSk7XHJcblxyXG4vKipcclxuICogQ2hlY2tzIGlmIHRoZSBjdXJyZW50IG9wZXJhdGluZyBzeXN0ZW0gaXMgV2luZG93cy5cclxuICpcclxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgb3BlcmF0aW5nIHN5c3RlbSBpcyBXaW5kb3dzLCBvdGhlcndpc2UgZmFsc2UuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gSXNXaW5kb3dzKCkge1xyXG4gICAgcmV0dXJuIGVudmlyb25tZW50Q2FjaGUuT1MgPT09IFwid2luZG93c1wiO1xyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2tzIGlmIHRoZSBjdXJyZW50IG9wZXJhdGluZyBzeXN0ZW0gaXMgTGludXguXHJcbiAqXHJcbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIHRydWUgaWYgdGhlIGN1cnJlbnQgb3BlcmF0aW5nIHN5c3RlbSBpcyBMaW51eCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIElzTGludXgoKSB7XHJcbiAgICByZXR1cm4gZW52aXJvbm1lbnRDYWNoZS5PUyA9PT0gXCJsaW51eFwiO1xyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2tzIGlmIHRoZSBjdXJyZW50IGVudmlyb25tZW50IGlzIGEgbWFjT1Mgb3BlcmF0aW5nIHN5c3RlbS5cclxuICpcclxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIGVudmlyb25tZW50IGlzIG1hY09TLCBmYWxzZSBvdGhlcndpc2UuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gSXNNYWMoKSB7XHJcbiAgICByZXR1cm4gZW52aXJvbm1lbnRDYWNoZS5PUyA9PT0gXCJkYXJ3aW5cIjtcclxufVxyXG5cclxuLyoqXHJcbiAqIENoZWNrcyBpZiB0aGUgY3VycmVudCBlbnZpcm9ubWVudCBhcmNoaXRlY3R1cmUgaXMgQU1ENjQuXHJcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBjdXJyZW50IGVudmlyb25tZW50IGFyY2hpdGVjdHVyZSBpcyBBTUQ2NCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIElzQU1ENjQoKSB7XHJcbiAgICByZXR1cm4gZW52aXJvbm1lbnRDYWNoZS5BcmNoID09PSBcImFtZDY0XCI7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDaGVja3MgaWYgdGhlIGN1cnJlbnQgYXJjaGl0ZWN0dXJlIGlzIEFSTS5cclxuICpcclxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIGN1cnJlbnQgYXJjaGl0ZWN0dXJlIGlzIEFSTSwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIElzQVJNKCkge1xyXG4gICAgcmV0dXJuIGVudmlyb25tZW50Q2FjaGUuQXJjaCA9PT0gXCJhcm1cIjtcclxufVxyXG5cclxuLyoqXHJcbiAqIENoZWNrcyBpZiB0aGUgY3VycmVudCBlbnZpcm9ubWVudCBpcyBBUk02NCBhcmNoaXRlY3R1cmUuXHJcbiAqXHJcbiAqIEByZXR1cm5zIHtib29sZWFufSAtIFJldHVybnMgdHJ1ZSBpZiB0aGUgZW52aXJvbm1lbnQgaXMgQVJNNjQgYXJjaGl0ZWN0dXJlLCBvdGhlcndpc2UgcmV0dXJucyBmYWxzZS5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBJc0FSTTY0KCkge1xyXG4gICAgcmV0dXJuIGVudmlyb25tZW50Q2FjaGUuQXJjaCA9PT0gXCJhcm02NFwiO1xyXG59XHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmNvbnN0IGNhbGwgPSBuZXdSdW50aW1lQ2FsbGVyV2l0aElEKG9iamVjdE5hbWVzLkJyb3dzZXIsICcnKTtcclxuY29uc3QgQnJvd3Nlck9wZW5VUkwgPSAwO1xyXG5cclxuLyoqXHJcbiAqIE9wZW4gYSBicm93c2VyIHdpbmRvdyB0byB0aGUgZ2l2ZW4gVVJMXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgLSBUaGUgVVJMIHRvIG9wZW5cclxuICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nPn1cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBPcGVuVVJMKHVybCkge1xyXG4gICAgcmV0dXJuIGNhbGwoQnJvd3Nlck9wZW5VUkwsIHt1cmx9KTtcclxufVxyXG4iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuLyoganNoaW50IGVzdmVyc2lvbjogOSAqL1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlZGVmIHtpbXBvcnQoXCIuLi9hcGkvdHlwZXNcIikuU2l6ZX0gU2l6ZVxyXG4gKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi4vYXBpL3R5cGVzXCIpLlBvc2l0aW9ufSBQb3NpdGlvblxyXG4gKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi4vYXBpL3R5cGVzXCIpLlNjcmVlbn0gU2NyZWVuXHJcbiAqL1xyXG5cclxuaW1wb3J0IHtuZXdSdW50aW1lQ2FsbGVyV2l0aElELCBvYmplY3ROYW1lc30gZnJvbSBcIi4vcnVudGltZVwiO1xyXG5cclxuY29uc3QgY2VudGVyID0gMDtcclxuY29uc3Qgc2V0VGl0bGUgPSAxO1xyXG5jb25zdCBmdWxsc2NyZWVuID0gMjtcclxuY29uc3QgdW5GdWxsc2NyZWVuID0gMztcclxuY29uc3Qgc2V0U2l6ZSA9IDQ7XHJcbmNvbnN0IHNpemUgPSA1O1xyXG5jb25zdCBzZXRNYXhTaXplID0gNjtcclxuY29uc3Qgc2V0TWluU2l6ZSA9IDc7XHJcbmNvbnN0IHNldEFsd2F5c09uVG9wID0gODtcclxuY29uc3Qgc2V0UmVsYXRpdmVQb3NpdGlvbiA9IDk7XHJcbmNvbnN0IHJlbGF0aXZlUG9zaXRpb24gPSAxMDtcclxuY29uc3Qgc2NyZWVuID0gMTE7XHJcbmNvbnN0IGhpZGUgPSAxMjtcclxuY29uc3QgbWF4aW1pc2UgPSAxMztcclxuY29uc3QgdW5NYXhpbWlzZSA9IDE0O1xyXG5jb25zdCB0b2dnbGVNYXhpbWlzZSA9IDE1O1xyXG5jb25zdCBtaW5pbWlzZSA9IDE2O1xyXG5jb25zdCB1bk1pbmltaXNlID0gMTc7XHJcbmNvbnN0IHJlc3RvcmUgPSAxODtcclxuY29uc3Qgc2hvdyA9IDE5O1xyXG5jb25zdCBjbG9zZSA9IDIwO1xyXG5jb25zdCBzZXRCYWNrZ3JvdW5kQ29sb3VyID0gMjE7XHJcbmNvbnN0IHNldFJlc2l6YWJsZSA9IDIyO1xyXG5jb25zdCB3aWR0aCA9IDIzO1xyXG5jb25zdCBoZWlnaHQgPSAyNDtcclxuY29uc3Qgem9vbUluID0gMjU7XHJcbmNvbnN0IHpvb21PdXQgPSAyNjtcclxuY29uc3Qgem9vbVJlc2V0ID0gMjc7XHJcbmNvbnN0IGdldFpvb21MZXZlbCA9IDI4O1xyXG5jb25zdCBzZXRab29tTGV2ZWwgPSAyOTtcclxuXHJcbmNvbnN0IHRoaXNXaW5kb3cgPSBuZXdSdW50aW1lQ2FsbGVyV2l0aElEKG9iamVjdE5hbWVzLldpbmRvdywgJycpO1xyXG5cclxuZnVuY3Rpb24gY3JlYXRlV2luZG93KGNhbGwpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgR2V0OiAod2luZG93TmFtZSkgPT4gY3JlYXRlV2luZG93KG5ld1J1bnRpbWVDYWxsZXJXaXRoSUQob2JqZWN0TmFtZXMuV2luZG93LCB3aW5kb3dOYW1lKSksXHJcbiAgICAgICAgQ2VudGVyOiAoKSA9PiBjYWxsKGNlbnRlciksXHJcbiAgICAgICAgU2V0VGl0bGU6ICh0aXRsZSkgPT4gY2FsbChzZXRUaXRsZSwge3RpdGxlfSksXHJcbiAgICAgICAgRnVsbHNjcmVlbjogKCkgPT4gY2FsbChmdWxsc2NyZWVuKSxcclxuICAgICAgICBVbkZ1bGxzY3JlZW46ICgpID0+IGNhbGwodW5GdWxsc2NyZWVuKSxcclxuICAgICAgICBTZXRTaXplOiAod2lkdGgsIGhlaWdodCkgPT4gY2FsbChzZXRTaXplLCB7d2lkdGgsIGhlaWdodH0pLFxyXG4gICAgICAgIFNpemU6ICgpID0+IGNhbGwoc2l6ZSksXHJcbiAgICAgICAgU2V0TWF4U2l6ZTogKHdpZHRoLCBoZWlnaHQpID0+IGNhbGwoc2V0TWF4U2l6ZSwge3dpZHRoLCBoZWlnaHR9KSxcclxuICAgICAgICBTZXRNaW5TaXplOiAod2lkdGgsIGhlaWdodCkgPT4gY2FsbChzZXRNaW5TaXplLCB7d2lkdGgsIGhlaWdodH0pLFxyXG4gICAgICAgIFNldEFsd2F5c09uVG9wOiAob25Ub3ApID0+IGNhbGwoc2V0QWx3YXlzT25Ub3AsIHthbHdheXNPblRvcDogb25Ub3B9KSxcclxuICAgICAgICBTZXRSZWxhdGl2ZVBvc2l0aW9uOiAoeCwgeSkgPT4gY2FsbChzZXRSZWxhdGl2ZVBvc2l0aW9uLCB7eCwgeX0pLFxyXG4gICAgICAgIFJlbGF0aXZlUG9zaXRpb246ICgpID0+IGNhbGwocmVsYXRpdmVQb3NpdGlvbiksXHJcbiAgICAgICAgU2NyZWVuOiAoKSA9PiBjYWxsKHNjcmVlbiksXHJcbiAgICAgICAgSGlkZTogKCkgPT4gY2FsbChoaWRlKSxcclxuICAgICAgICBNYXhpbWlzZTogKCkgPT4gY2FsbChtYXhpbWlzZSksXHJcbiAgICAgICAgVW5NYXhpbWlzZTogKCkgPT4gY2FsbCh1bk1heGltaXNlKSxcclxuICAgICAgICBUb2dnbGVNYXhpbWlzZTogKCkgPT4gY2FsbCh0b2dnbGVNYXhpbWlzZSksXHJcbiAgICAgICAgTWluaW1pc2U6ICgpID0+IGNhbGwobWluaW1pc2UpLFxyXG4gICAgICAgIFVuTWluaW1pc2U6ICgpID0+IGNhbGwodW5NaW5pbWlzZSksXHJcbiAgICAgICAgUmVzdG9yZTogKCkgPT4gY2FsbChyZXN0b3JlKSxcclxuICAgICAgICBTaG93OiAoKSA9PiBjYWxsKHNob3cpLFxyXG4gICAgICAgIENsb3NlOiAoKSA9PiBjYWxsKGNsb3NlKSxcclxuICAgICAgICBTZXRCYWNrZ3JvdW5kQ29sb3VyOiAociwgZywgYiwgYSkgPT4gY2FsbChzZXRCYWNrZ3JvdW5kQ29sb3VyLCB7ciwgZywgYiwgYX0pLFxyXG4gICAgICAgIFNldFJlc2l6YWJsZTogKHJlc2l6YWJsZSkgPT4gY2FsbChzZXRSZXNpemFibGUsIHtyZXNpemFibGV9KSxcclxuICAgICAgICBXaWR0aDogKCkgPT4gY2FsbCh3aWR0aCksXHJcbiAgICAgICAgSGVpZ2h0OiAoKSA9PiBjYWxsKGhlaWdodCksXHJcbiAgICAgICAgWm9vbUluOiAoKSA9PiBjYWxsKHpvb21JbiksXHJcbiAgICAgICAgWm9vbU91dDogKCkgPT4gY2FsbCh6b29tT3V0KSxcclxuICAgICAgICBab29tUmVzZXQ6ICgpID0+IGNhbGwoem9vbVJlc2V0KSxcclxuICAgICAgICBHZXRab29tTGV2ZWw6ICgpID0+IGNhbGwoZ2V0Wm9vbUxldmVsKSxcclxuICAgICAgICBTZXRab29tTGV2ZWw6ICh6b29tTGV2ZWwpID0+IGNhbGwoc2V0Wm9vbUxldmVsLCB7em9vbUxldmVsfSksXHJcbiAgICB9O1xyXG59XHJcblxyXG4vKipcclxuICogR2V0cyB0aGUgc3BlY2lmaWVkIHdpbmRvdy5cclxuICpcclxuICogQHBhcmFtIHtzdHJpbmd9IHdpbmRvd05hbWUgLSBUaGUgbmFtZSBvZiB0aGUgd2luZG93IHRvIGdldC5cclxuICogQHJldHVybiB7T2JqZWN0fSAtIFRoZSBzcGVjaWZpZWQgd2luZG93IG9iamVjdC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBHZXQod2luZG93TmFtZSkge1xyXG4gICAgcmV0dXJuIGNyZWF0ZVdpbmRvdyhuZXdSdW50aW1lQ2FsbGVyV2l0aElEKG9iamVjdE5hbWVzLldpbmRvdywgd2luZG93TmFtZSkpO1xyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJucyBhIG1hcCBvZiBhbGwgbWV0aG9kcyBpbiB0aGUgY3VycmVudCB3aW5kb3cuXHJcbiAqIEByZXR1cm5zIHtNYXB9IC0gQSBtYXAgb2Ygd2luZG93IG1ldGhvZHMuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gV2luZG93TWV0aG9kcyh0YXJnZXRXaW5kb3cpIHtcclxuICAgIC8vIENyZWF0ZSBhIG5ldyBtYXAgdG8gc3RvcmUgbWV0aG9kc1xyXG4gICAgbGV0IHJlc3VsdCA9IG5ldyBNYXAoKTtcclxuXHJcbiAgICAvLyBJdGVyYXRlIG92ZXIgYWxsIHByb3BlcnRpZXMgb2YgdGhlIHdpbmRvdyBvYmplY3RcclxuICAgIGZvciAobGV0IG1ldGhvZCBpbiB0YXJnZXRXaW5kb3cpIHtcclxuICAgICAgICAvLyBDaGVjayBpZiB0aGUgcHJvcGVydHkgaXMgaW5kZWVkIGEgbWV0aG9kIChmdW5jdGlvbilcclxuICAgICAgICBpZih0eXBlb2YgdGFyZ2V0V2luZG93W21ldGhvZF0gPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgLy8gQWRkIHRoZSBtZXRob2QgdG8gdGhlIG1hcFxyXG4gICAgICAgICAgICByZXN1bHQuc2V0KG1ldGhvZCwgdGFyZ2V0V2luZG93W21ldGhvZF0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9XHJcbiAgICAvLyBSZXR1cm4gdGhlIG1hcCBvZiB3aW5kb3cgbWV0aG9kc1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5leHBvcnQgZGVmYXVsdCB7XHJcbiAgICAuLi5HZXQoJycpXHJcbn1cclxuIiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuaW1wb3J0IHsgbmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXMgfSBmcm9tIFwiLi9ydW50aW1lXCI7XHJcbmltcG9ydCB7IG5hbm9pZCB9IGZyb20gJ25hbm9pZC9ub24tc2VjdXJlJztcclxuXHJcbmNvbnN0IENhbGxCaW5kaW5nID0gMDtcclxuY29uc3QgY2FsbCA9IG5ld1J1bnRpbWVDYWxsZXJXaXRoSUQob2JqZWN0TmFtZXMuQ2FsbCwgJycpO1xyXG5sZXQgY2FsbFJlc3BvbnNlcyA9IG5ldyBNYXAoKTtcclxuXHJcbndpbmRvdy5fd2FpbHMgPSB3aW5kb3cuX3dhaWxzIHx8IHt9O1xyXG53aW5kb3cuX3dhaWxzLmNhbGxDYWxsYmFjayA9IHJlc3VsdEhhbmRsZXI7XHJcbndpbmRvdy5fd2FpbHMuY2FsbEVycm9yQ2FsbGJhY2sgPSBlcnJvckhhbmRsZXI7XHJcblxyXG5mdW5jdGlvbiBnZW5lcmF0ZUlEKCkge1xyXG4gICAgbGV0IHJlc3VsdDtcclxuICAgIGRvIHtcclxuICAgICAgICByZXN1bHQgPSBuYW5vaWQoKTtcclxuICAgIH0gd2hpbGUgKGNhbGxSZXNwb25zZXMuaGFzKHJlc3VsdCkpO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHJlc3VsdEhhbmRsZXIoaWQsIGRhdGEsIGlzSlNPTikge1xyXG4gICAgY29uc3QgcHJvbWlzZUhhbmRsZXIgPSBnZXRBbmREZWxldGVSZXNwb25zZShpZCk7XHJcbiAgICBpZiAocHJvbWlzZUhhbmRsZXIpIHtcclxuICAgICAgICBwcm9taXNlSGFuZGxlci5yZXNvbHZlKGlzSlNPTiA/IEpTT04ucGFyc2UoZGF0YSkgOiBkYXRhKTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGVycm9ySGFuZGxlcihpZCwgbWVzc2FnZSkge1xyXG4gICAgY29uc3QgcHJvbWlzZUhhbmRsZXIgPSBnZXRBbmREZWxldGVSZXNwb25zZShpZCk7XHJcbiAgICBpZiAocHJvbWlzZUhhbmRsZXIpIHtcclxuICAgICAgICBwcm9taXNlSGFuZGxlci5yZWplY3QobWVzc2FnZSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldEFuZERlbGV0ZVJlc3BvbnNlKGlkKSB7XHJcbiAgICBjb25zdCByZXNwb25zZSA9IGNhbGxSZXNwb25zZXMuZ2V0KGlkKTtcclxuICAgIGNhbGxSZXNwb25zZXMuZGVsZXRlKGlkKTtcclxuICAgIHJldHVybiByZXNwb25zZTtcclxufVxyXG5cclxuZnVuY3Rpb24gY2FsbEJpbmRpbmcodHlwZSwgb3B0aW9ucyA9IHt9KSB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgIGNvbnN0IGlkID0gZ2VuZXJhdGVJRCgpO1xyXG4gICAgICAgIG9wdGlvbnNbXCJjYWxsLWlkXCJdID0gaWQ7XHJcbiAgICAgICAgY2FsbFJlc3BvbnNlcy5zZXQoaWQsIHsgcmVzb2x2ZSwgcmVqZWN0IH0pO1xyXG4gICAgICAgIGNhbGwodHlwZSwgb3B0aW9ucykuY2F0Y2goKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAgIHJlamVjdChlcnJvcik7XHJcbiAgICAgICAgICAgIGNhbGxSZXNwb25zZXMuZGVsZXRlKGlkKTtcclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG59XHJcblxyXG4vKipcclxuICogQ2FsbCBtZXRob2QuXHJcbiAqXHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gVGhlIG9wdGlvbnMgZm9yIHRoZSBtZXRob2QuXHJcbiAqIEByZXR1cm5zIHtPYmplY3R9IC0gVGhlIHJlc3VsdCBvZiB0aGUgY2FsbC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBDYWxsKG9wdGlvbnMpIHtcclxuICAgIHJldHVybiBjYWxsQmluZGluZyhDYWxsQmluZGluZywgb3B0aW9ucyk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBFeGVjdXRlcyBhIG1ldGhvZCBieSBuYW1lLlxyXG4gKlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBtZXRob2QgaW4gdGhlIGZvcm1hdCAncGFja2FnZS5zdHJ1Y3QubWV0aG9kJy5cclxuICogQHBhcmFtIHsuLi4qfSBhcmdzIC0gVGhlIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBtZXRob2QuXHJcbiAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUgbmFtZSBpcyBub3QgYSBzdHJpbmcgb3IgaXMgbm90IGluIHRoZSBjb3JyZWN0IGZvcm1hdC5cclxuICogQHJldHVybnMgeyp9IFRoZSByZXN1bHQgb2YgdGhlIG1ldGhvZCBleGVjdXRpb24uXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gQnlOYW1lKG5hbWUsIC4uLmFyZ3MpIHtcclxuICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gXCJzdHJpbmdcIiB8fCBuYW1lLnNwbGl0KFwiLlwiKS5sZW5ndGggIT09IDMpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYWxsQnlOYW1lIHJlcXVpcmVzIGEgc3RyaW5nIGluIHRoZSBmb3JtYXQgJ3BhY2thZ2Uuc3RydWN0Lm1ldGhvZCdcIik7XHJcbiAgICB9XHJcbiAgICBsZXQgW3BhY2thZ2VOYW1lLCBzdHJ1Y3ROYW1lLCBtZXRob2ROYW1lXSA9IG5hbWUuc3BsaXQoXCIuXCIpO1xyXG4gICAgcmV0dXJuIGNhbGxCaW5kaW5nKENhbGxCaW5kaW5nLCB7XHJcbiAgICAgICAgcGFja2FnZU5hbWUsXHJcbiAgICAgICAgc3RydWN0TmFtZSxcclxuICAgICAgICBtZXRob2ROYW1lLFxyXG4gICAgICAgIGFyZ3NcclxuICAgIH0pO1xyXG59XHJcblxyXG4vKipcclxuICogQ2FsbHMgYSBtZXRob2QgYnkgaXRzIElEIHdpdGggdGhlIHNwZWNpZmllZCBhcmd1bWVudHMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXRob2RJRCAtIFRoZSBJRCBvZiB0aGUgbWV0aG9kIHRvIGNhbGwuXHJcbiAqIEBwYXJhbSB7Li4uKn0gYXJncyAtIFRoZSBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgbWV0aG9kLlxyXG4gKiBAcmV0dXJuIHsqfSAtIFRoZSByZXN1bHQgb2YgdGhlIG1ldGhvZCBjYWxsLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIEJ5SUQobWV0aG9kSUQsIC4uLmFyZ3MpIHtcclxuICAgIHJldHVybiBjYWxsQmluZGluZyhDYWxsQmluZGluZywge1xyXG4gICAgICAgIG1ldGhvZElELFxyXG4gICAgICAgIGFyZ3NcclxuICAgIH0pO1xyXG59XHJcblxyXG4vKipcclxuICogQ2FsbHMgYSBtZXRob2Qgb24gYSBwbHVnaW4uXHJcbiAqXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBwbHVnaW5OYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHBsdWdpbi5cclxuICogQHBhcmFtIHtzdHJpbmd9IG1ldGhvZE5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgbWV0aG9kIHRvIGNhbGwuXHJcbiAqIEBwYXJhbSB7Li4uKn0gYXJncyAtIFRoZSBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGUgbWV0aG9kLlxyXG4gKiBAcmV0dXJucyB7Kn0gLSBUaGUgcmVzdWx0IG9mIHRoZSBtZXRob2QgY2FsbC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBQbHVnaW4ocGx1Z2luTmFtZSwgbWV0aG9kTmFtZSwgLi4uYXJncykge1xyXG4gICAgcmV0dXJuIGNhbGxCaW5kaW5nKENhbGxCaW5kaW5nLCB7XHJcbiAgICAgICAgcGFja2FnZU5hbWU6IFwid2FpbHMtcGx1Z2luc1wiLFxyXG4gICAgICAgIHN0cnVjdE5hbWU6IHBsdWdpbk5hbWUsXHJcbiAgICAgICAgbWV0aG9kTmFtZSxcclxuICAgICAgICBhcmdzXHJcbiAgICB9KTtcclxufVxyXG4iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuLyoganNoaW50IGVzdmVyc2lvbjogOSAqL1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL3R5cGVzXCIpLldhaWxzRXZlbnR9IFdhaWxzRXZlbnRcclxuICovXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmNvbnN0IGNhbGwgPSBuZXdSdW50aW1lQ2FsbGVyV2l0aElEKG9iamVjdE5hbWVzLkV2ZW50cywgJycpO1xyXG5jb25zdCBFbWl0TWV0aG9kID0gMDtcclxuY29uc3QgZXZlbnRMaXN0ZW5lcnMgPSBuZXcgTWFwKCk7XHJcblxyXG5jbGFzcyBMaXN0ZW5lciB7XHJcbiAgICBjb25zdHJ1Y3RvcihldmVudE5hbWUsIGNhbGxiYWNrLCBtYXhDYWxsYmFja3MpIHtcclxuICAgICAgICB0aGlzLmV2ZW50TmFtZSA9IGV2ZW50TmFtZTtcclxuICAgICAgICB0aGlzLm1heENhbGxiYWNrcyA9IG1heENhbGxiYWNrcyB8fCAtMTtcclxuICAgICAgICB0aGlzLkNhbGxiYWNrID0gKGRhdGEpID0+IHtcclxuICAgICAgICAgICAgY2FsbGJhY2soZGF0YSk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLm1heENhbGxiYWNrcyA9PT0gLTEpIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy5tYXhDYWxsYmFja3MgLT0gMTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubWF4Q2FsbGJhY2tzID09PSAwO1xyXG4gICAgICAgIH07XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBXYWlsc0V2ZW50IHtcclxuICAgIGNvbnN0cnVjdG9yKG5hbWUsIGRhdGEgPSBudWxsKSB7XHJcbiAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcclxuICAgICAgICB0aGlzLmRhdGEgPSBkYXRhO1xyXG4gICAgfVxyXG59XHJcblxyXG5cclxud2luZG93Ll93YWlscyA9IHdpbmRvdy5fd2FpbHMgfHwge307XHJcbndpbmRvdy5fd2FpbHMuZGlzcGF0Y2hXYWlsc0V2ZW50ID0gZGlzcGF0Y2hXYWlsc0V2ZW50O1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGRpc3BhdGNoV2FpbHNFdmVudChldmVudCkge1xyXG4gICAgbGV0IGxpc3RlbmVycyA9IGV2ZW50TGlzdGVuZXJzLmdldChldmVudC5uYW1lKTtcclxuICAgIGlmIChsaXN0ZW5lcnMpIHtcclxuICAgICAgICBsZXQgdG9SZW1vdmUgPSBsaXN0ZW5lcnMuZmlsdGVyKGxpc3RlbmVyID0+IHtcclxuICAgICAgICAgICAgbGV0IHJlbW92ZSA9IGxpc3RlbmVyLkNhbGxiYWNrKGV2ZW50KTtcclxuICAgICAgICAgICAgaWYgKHJlbW92ZSkgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgaWYgKHRvUmVtb3ZlLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgbGlzdGVuZXJzID0gbGlzdGVuZXJzLmZpbHRlcihsID0+ICF0b1JlbW92ZS5pbmNsdWRlcyhsKSk7XHJcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMubGVuZ3RoID09PSAwKSBldmVudExpc3RlbmVycy5kZWxldGUoZXZlbnQubmFtZSk7XHJcbiAgICAgICAgICAgIGVsc2UgZXZlbnRMaXN0ZW5lcnMuc2V0KGV2ZW50Lm5hbWUsIGxpc3RlbmVycyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogUmVnaXN0ZXIgYSBjYWxsYmFjayBmdW5jdGlvbiB0byBiZSBjYWxsZWQgbXVsdGlwbGUgdGltZXMgZm9yIGEgc3BlY2lmaWMgZXZlbnQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVnaXN0ZXIgdGhlIGNhbGxiYWNrIGZvci5cclxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgLSBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gdG8gYmUgY2FsbGVkIHdoZW4gdGhlIGV2ZW50IGlzIHRyaWdnZXJlZC5cclxuICogQHBhcmFtIHtudW1iZXJ9IG1heENhbGxiYWNrcyAtIFRoZSBtYXhpbXVtIG51bWJlciBvZiB0aW1lcyB0aGUgY2FsbGJhY2sgY2FuIGJlIGNhbGxlZCBmb3IgdGhlIGV2ZW50LiBPbmNlIHRoZSBtYXhpbXVtIG51bWJlciBpcyByZWFjaGVkLCB0aGUgY2FsbGJhY2sgd2lsbCBubyBsb25nZXIgYmUgY2FsbGVkLlxyXG4gKlxyXG4gQHJldHVybiB7ZnVuY3Rpb259IC0gQSBmdW5jdGlvbiB0aGF0LCB3aGVuIGNhbGxlZCwgd2lsbCB1bnJlZ2lzdGVyIHRoZSBjYWxsYmFjayBmcm9tIHRoZSBldmVudC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBPbk11bHRpcGxlKGV2ZW50TmFtZSwgY2FsbGJhY2ssIG1heENhbGxiYWNrcykge1xyXG4gICAgbGV0IGxpc3RlbmVycyA9IGV2ZW50TGlzdGVuZXJzLmdldChldmVudE5hbWUpIHx8IFtdO1xyXG4gICAgY29uc3QgdGhpc0xpc3RlbmVyID0gbmV3IExpc3RlbmVyKGV2ZW50TmFtZSwgY2FsbGJhY2ssIG1heENhbGxiYWNrcyk7XHJcbiAgICBsaXN0ZW5lcnMucHVzaCh0aGlzTGlzdGVuZXIpO1xyXG4gICAgZXZlbnRMaXN0ZW5lcnMuc2V0KGV2ZW50TmFtZSwgbGlzdGVuZXJzKTtcclxuICAgIHJldHVybiAoKSA9PiBsaXN0ZW5lck9mZih0aGlzTGlzdGVuZXIpO1xyXG59XHJcblxyXG4vKipcclxuICogUmVnaXN0ZXJzIGEgY2FsbGJhY2sgZnVuY3Rpb24gdG8gYmUgZXhlY3V0ZWQgd2hlbiB0aGUgc3BlY2lmaWVkIGV2ZW50IG9jY3Vycy5cclxuICpcclxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBldmVudC5cclxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgLSBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gdG8gYmUgZXhlY3V0ZWQuIEl0IHRha2VzIG5vIHBhcmFtZXRlcnMuXHJcbiAqIEByZXR1cm4ge2Z1bmN0aW9ufSAtIEEgZnVuY3Rpb24gdGhhdCwgd2hlbiBjYWxsZWQsIHdpbGwgdW5yZWdpc3RlciB0aGUgY2FsbGJhY2sgZnJvbSB0aGUgZXZlbnQuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBPbihldmVudE5hbWUsIGNhbGxiYWNrKSB7IHJldHVybiBPbk11bHRpcGxlKGV2ZW50TmFtZSwgY2FsbGJhY2ssIC0xKTsgfVxyXG5cclxuLyoqXHJcbiAqIFJlZ2lzdGVycyBhIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIG9ubHkgb25jZSBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cclxuICpcclxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBldmVudC5cclxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2sgLSBUaGUgZnVuY3Rpb24gdG8gYmUgZXhlY3V0ZWQgd2hlbiB0aGUgZXZlbnQgb2NjdXJzLlxyXG4gKiBAcmV0dXJuIHt2b2lkQHJldHVybiB7ZnVuY3Rpb259IC0gQSBmdW5jdGlvbiB0aGF0LCB3aGVuIGNhbGxlZCwgd2lsbCB1bnJlZ2lzdGVyIHRoZSBjYWxsYmFjayBmcm9tIHRoZSBldmVudC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBPbmNlKGV2ZW50TmFtZSwgY2FsbGJhY2spIHsgcmV0dXJuIE9uTXVsdGlwbGUoZXZlbnROYW1lLCBjYWxsYmFjaywgMSk7IH1cclxuXHJcbi8qKlxyXG4gKiBSZW1vdmVzIHRoZSBzcGVjaWZpZWQgbGlzdGVuZXIgZnJvbSB0aGUgZXZlbnQgbGlzdGVuZXJzIGNvbGxlY3Rpb24uXHJcbiAqIElmIGFsbCBsaXN0ZW5lcnMgZm9yIHRoZSBldmVudCBhcmUgcmVtb3ZlZCwgdGhlIGV2ZW50IGtleSBpcyBkZWxldGVkIGZyb20gdGhlIGNvbGxlY3Rpb24uXHJcbiAqXHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBsaXN0ZW5lciAtIFRoZSBsaXN0ZW5lciB0byBiZSByZW1vdmVkLlxyXG4gKi9cclxuZnVuY3Rpb24gbGlzdGVuZXJPZmYobGlzdGVuZXIpIHtcclxuICAgIGNvbnN0IGV2ZW50TmFtZSA9IGxpc3RlbmVyLmV2ZW50TmFtZTtcclxuICAgIGxldCBsaXN0ZW5lcnMgPSBldmVudExpc3RlbmVycy5nZXQoZXZlbnROYW1lKS5maWx0ZXIobCA9PiBsICE9PSBsaXN0ZW5lcik7XHJcbiAgICBpZiAobGlzdGVuZXJzLmxlbmd0aCA9PT0gMCkgZXZlbnRMaXN0ZW5lcnMuZGVsZXRlKGV2ZW50TmFtZSk7XHJcbiAgICBlbHNlIGV2ZW50TGlzdGVuZXJzLnNldChldmVudE5hbWUsIGxpc3RlbmVycyk7XHJcbn1cclxuXHJcblxyXG4vKipcclxuICogUmVtb3ZlcyBldmVudCBsaXN0ZW5lcnMgZm9yIHRoZSBzcGVjaWZpZWQgZXZlbnQgbmFtZXMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gcmVtb3ZlIGxpc3RlbmVycyBmb3IuXHJcbiAqIEBwYXJhbSB7Li4uc3RyaW5nfSBhZGRpdGlvbmFsRXZlbnROYW1lcyAtIEFkZGl0aW9uYWwgZXZlbnQgbmFtZXMgdG8gcmVtb3ZlIGxpc3RlbmVycyBmb3IuXHJcbiAqIEByZXR1cm4ge3VuZGVmaW5lZH1cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBPZmYoZXZlbnROYW1lLCAuLi5hZGRpdGlvbmFsRXZlbnROYW1lcykge1xyXG4gICAgbGV0IGV2ZW50c1RvUmVtb3ZlID0gW2V2ZW50TmFtZSwgLi4uYWRkaXRpb25hbEV2ZW50TmFtZXNdO1xyXG4gICAgZXZlbnRzVG9SZW1vdmUuZm9yRWFjaChldmVudE5hbWUgPT4gZXZlbnRMaXN0ZW5lcnMuZGVsZXRlKGV2ZW50TmFtZSkpO1xyXG59XHJcbi8qKlxyXG4gKiBSZW1vdmVzIGFsbCBldmVudCBsaXN0ZW5lcnMuXHJcbiAqXHJcbiAqIEBmdW5jdGlvbiBPZmZBbGxcclxuICogQHJldHVybnMge3ZvaWR9XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gT2ZmQWxsKCkgeyBldmVudExpc3RlbmVycy5jbGVhcigpOyB9XHJcblxyXG4vKipcclxuICogRW1pdHMgYW4gZXZlbnQgdXNpbmcgdGhlIGdpdmVuIGV2ZW50IG5hbWUuXHJcbiAqXHJcbiAqIEBwYXJhbSB7V2FpbHNFdmVudH0gZXZlbnQgLSBUaGUgbmFtZSBvZiB0aGUgZXZlbnQgdG8gZW1pdC5cclxuICogQHJldHVybnMge2FueX0gLSBUaGUgcmVzdWx0IG9mIHRoZSBlbWl0dGVkIGV2ZW50LlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIEVtaXQoZXZlbnQpIHsgcmV0dXJuIGNhbGwoRW1pdE1ldGhvZCwgZXZlbnQpOyB9XHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcblxyXG4vKipcclxuICogQHR5cGVkZWYge2ltcG9ydChcIi4vdHlwZXNcIikuTWVzc2FnZURpYWxvZ09wdGlvbnN9IE1lc3NhZ2VEaWFsb2dPcHRpb25zXHJcbiAqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL3R5cGVzXCIpLk9wZW5EaWFsb2dPcHRpb25zfSBPcGVuRGlhbG9nT3B0aW9uc1xyXG4gKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi90eXBlc1wiKS5TYXZlRGlhbG9nT3B0aW9uc30gU2F2ZURpYWxvZ09wdGlvbnNcclxuICovXHJcblxyXG5pbXBvcnQge25ld1J1bnRpbWVDYWxsZXJXaXRoSUQsIG9iamVjdE5hbWVzfSBmcm9tIFwiLi9ydW50aW1lXCI7XHJcblxyXG5pbXBvcnQgeyBuYW5vaWQgfSBmcm9tICduYW5vaWQvbm9uLXNlY3VyZSc7XHJcblxyXG4vLyBEZWZpbmUgY29uc3RhbnRzIGZyb20gdGhlIGBtZXRob2RzYCBvYmplY3QgaW4gVGl0bGUgQ2FzZVxyXG5jb25zdCBEaWFsb2dJbmZvID0gMDtcclxuY29uc3QgRGlhbG9nV2FybmluZyA9IDE7XHJcbmNvbnN0IERpYWxvZ0Vycm9yID0gMjtcclxuY29uc3QgRGlhbG9nUXVlc3Rpb24gPSAzO1xyXG5jb25zdCBEaWFsb2dPcGVuRmlsZSA9IDQ7XHJcbmNvbnN0IERpYWxvZ1NhdmVGaWxlID0gNTtcclxuXHJcbmNvbnN0IGNhbGwgPSBuZXdSdW50aW1lQ2FsbGVyV2l0aElEKG9iamVjdE5hbWVzLkRpYWxvZywgJycpO1xyXG5jb25zdCBkaWFsb2dSZXNwb25zZXMgPSBuZXcgTWFwKCk7XHJcblxyXG4vKipcclxuICogR2VuZXJhdGVzIGEgdW5pcXVlIGlkIHRoYXQgaXMgbm90IHByZXNlbnQgaW4gZGlhbG9nUmVzcG9uc2VzLlxyXG4gKiBAcmV0dXJucyB7c3RyaW5nfSB1bmlxdWUgaWRcclxuICovXHJcbmZ1bmN0aW9uIGdlbmVyYXRlSUQoKSB7XHJcbiAgICBsZXQgcmVzdWx0O1xyXG4gICAgZG8ge1xyXG4gICAgICAgIHJlc3VsdCA9IG5hbm9pZCgpO1xyXG4gICAgfSB3aGlsZSAoZGlhbG9nUmVzcG9uc2VzLmhhcyhyZXN1bHQpKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBTaG93cyBhIGRpYWxvZyBvZiBzcGVjaWZpZWQgdHlwZSB3aXRoIHRoZSBnaXZlbiBvcHRpb25zLlxyXG4gKiBAcGFyYW0ge251bWJlcn0gdHlwZSAtIHR5cGUgb2YgZGlhbG9nXHJcbiAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zIC0gb3B0aW9ucyBmb3IgdGhlIGRpYWxvZ1xyXG4gKiBAcmV0dXJucyB7UHJvbWlzZX0gcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggcmVzdWx0IG9mIGRpYWxvZ1xyXG4gKi9cclxuZnVuY3Rpb24gZGlhbG9nKHR5cGUsIG9wdGlvbnMgPSB7fSkge1xyXG4gICAgY29uc3QgaWQgPSBnZW5lcmF0ZUlEKCk7XHJcbiAgICBvcHRpb25zW1wiZGlhbG9nLWlkXCJdID0gaWQ7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgIGRpYWxvZ1Jlc3BvbnNlcy5zZXQoaWQsIHtyZXNvbHZlLCByZWplY3R9KTtcclxuICAgICAgICBjYWxsKHR5cGUsIG9wdGlvbnMpLmNhdGNoKChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgICByZWplY3QoZXJyb3IpO1xyXG4gICAgICAgICAgICBkaWFsb2dSZXNwb25zZXMuZGVsZXRlKGlkKTtcclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG59XHJcblxyXG4vKipcclxuICogSGFuZGxlcyB0aGUgY2FsbGJhY2sgZnJvbSBhIGRpYWxvZy5cclxuICpcclxuICogQHBhcmFtIHtzdHJpbmd9IGlkIC0gVGhlIElEIG9mIHRoZSBkaWFsb2cgcmVzcG9uc2UuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBkYXRhIC0gVGhlIGRhdGEgcmVjZWl2ZWQgZnJvbSB0aGUgZGlhbG9nLlxyXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGlzSlNPTiAtIEZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHRoZSBkYXRhIGlzIGluIEpTT04gZm9ybWF0LlxyXG4gKlxyXG4gKiBAcmV0dXJuIHt1bmRlZmluZWR9XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZGlhbG9nQ2FsbGJhY2soaWQsIGRhdGEsIGlzSlNPTikge1xyXG4gICAgbGV0IHAgPSBkaWFsb2dSZXNwb25zZXMuZ2V0KGlkKTtcclxuICAgIGlmIChwKSB7XHJcbiAgICAgICAgaWYgKGlzSlNPTikge1xyXG4gICAgICAgICAgICBwLnJlc29sdmUoSlNPTi5wYXJzZShkYXRhKSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcC5yZXNvbHZlKGRhdGEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBkaWFsb2dSZXNwb25zZXMuZGVsZXRlKGlkKTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIENhbGxiYWNrIGZ1bmN0aW9uIGZvciBoYW5kbGluZyBlcnJvcnMgaW4gZGlhbG9nLlxyXG4gKlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gaWQgLSBUaGUgaWQgb2YgdGhlIGRpYWxvZyByZXNwb25zZS5cclxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBUaGUgZXJyb3IgbWVzc2FnZS5cclxuICpcclxuICogQHJldHVybiB7dm9pZH1cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBkaWFsb2dFcnJvckNhbGxiYWNrKGlkLCBtZXNzYWdlKSB7XHJcbiAgICBsZXQgcCA9IGRpYWxvZ1Jlc3BvbnNlcy5nZXQoaWQpO1xyXG4gICAgaWYgKHApIHtcclxuICAgICAgICBwLnJlamVjdChtZXNzYWdlKTtcclxuICAgICAgICBkaWFsb2dSZXNwb25zZXMuZGVsZXRlKGlkKTtcclxuICAgIH1cclxufVxyXG5cclxuXHJcbi8vIFJlcGxhY2UgYG1ldGhvZHNgIHdpdGggY29uc3RhbnRzIGluIFRpdGxlIENhc2VcclxuXHJcbi8qKlxyXG4gKiBAcGFyYW0ge01lc3NhZ2VEaWFsb2dPcHRpb25zfSBvcHRpb25zIC0gRGlhbG9nIG9wdGlvbnNcclxuICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nPn0gLSBUaGUgbGFiZWwgb2YgdGhlIGJ1dHRvbiBwcmVzc2VkXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgSW5mbyA9IChvcHRpb25zKSA9PiBkaWFsb2coRGlhbG9nSW5mbywgb3B0aW9ucyk7XHJcblxyXG4vKipcclxuICogQHBhcmFtIHtNZXNzYWdlRGlhbG9nT3B0aW9uc30gb3B0aW9ucyAtIERpYWxvZyBvcHRpb25zXHJcbiAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZz59IC0gVGhlIGxhYmVsIG9mIHRoZSBidXR0b24gcHJlc3NlZFxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IFdhcm5pbmcgPSAob3B0aW9ucykgPT4gZGlhbG9nKERpYWxvZ1dhcm5pbmcsIG9wdGlvbnMpO1xyXG5cclxuLyoqXHJcbiAqIEBwYXJhbSB7TWVzc2FnZURpYWxvZ09wdGlvbnN9IG9wdGlvbnMgLSBEaWFsb2cgb3B0aW9uc1xyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fSAtIFRoZSBsYWJlbCBvZiB0aGUgYnV0dG9uIHByZXNzZWRcclxuICovXHJcbmV4cG9ydCBjb25zdCBFcnJvciA9IChvcHRpb25zKSA9PiBkaWFsb2coRGlhbG9nRXJyb3IsIG9wdGlvbnMpO1xyXG5cclxuLyoqXHJcbiAqIEBwYXJhbSB7TWVzc2FnZURpYWxvZ09wdGlvbnN9IG9wdGlvbnMgLSBEaWFsb2cgb3B0aW9uc1xyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fSAtIFRoZSBsYWJlbCBvZiB0aGUgYnV0dG9uIHByZXNzZWRcclxuICovXHJcbmV4cG9ydCBjb25zdCBRdWVzdGlvbiA9IChvcHRpb25zKSA9PiBkaWFsb2coRGlhbG9nUXVlc3Rpb24sIG9wdGlvbnMpO1xyXG5cclxuLyoqXHJcbiAqIEBwYXJhbSB7T3BlbkRpYWxvZ09wdGlvbnN9IG9wdGlvbnMgLSBEaWFsb2cgb3B0aW9uc1xyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmdbXXxzdHJpbmc+fSBSZXR1cm5zIHNlbGVjdGVkIGZpbGUgb3IgbGlzdCBvZiBmaWxlcy4gUmV0dXJucyBibGFuayBzdHJpbmcgaWYgbm8gZmlsZSBpcyBzZWxlY3RlZC5cclxuICovXHJcbmV4cG9ydCBjb25zdCBPcGVuRmlsZSA9IChvcHRpb25zKSA9PiBkaWFsb2coRGlhbG9nT3BlbkZpbGUsIG9wdGlvbnMpO1xyXG5cclxuLyoqXHJcbiAqIEBwYXJhbSB7U2F2ZURpYWxvZ09wdGlvbnN9IG9wdGlvbnMgLSBEaWFsb2cgb3B0aW9uc1xyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fSBSZXR1cm5zIHRoZSBzZWxlY3RlZCBmaWxlLiBSZXR1cm5zIGJsYW5rIHN0cmluZyBpZiBubyBmaWxlIGlzIHNlbGVjdGVkLlxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IFNhdmVGaWxlID0gKG9wdGlvbnMpID0+IGRpYWxvZyhEaWFsb2dTYXZlRmlsZSwgb3B0aW9ucyk7XHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcblxyXG5pbXBvcnQge25ld1J1bnRpbWVDYWxsZXJXaXRoSUQsIG9iamVjdE5hbWVzfSBmcm9tIFwiLi9ydW50aW1lXCI7XHJcblxyXG5jb25zdCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5Db250ZXh0TWVudSwgJycpO1xyXG5jb25zdCBDb250ZXh0TWVudU9wZW4gPSAwO1xyXG5cclxuZnVuY3Rpb24gb3BlbkNvbnRleHRNZW51KGlkLCB4LCB5LCBkYXRhKSB7XHJcbiAgICB2b2lkIGNhbGwoQ29udGV4dE1lbnVPcGVuLCB7aWQsIHgsIHksIGRhdGF9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHNldHVwQ29udGV4dE1lbnVzKCkge1xyXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2NvbnRleHRtZW51JywgY29udGV4dE1lbnVIYW5kbGVyKTtcclxufVxyXG5cclxuZnVuY3Rpb24gY29udGV4dE1lbnVIYW5kbGVyKGV2ZW50KSB7XHJcbiAgICAvLyBDaGVjayBmb3IgY3VzdG9tIGNvbnRleHQgbWVudVxyXG4gICAgbGV0IGVsZW1lbnQgPSBldmVudC50YXJnZXQ7XHJcbiAgICBsZXQgY3VzdG9tQ29udGV4dE1lbnUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KS5nZXRQcm9wZXJ0eVZhbHVlKFwiLS1jdXN0b20tY29udGV4dG1lbnVcIik7XHJcbiAgICBjdXN0b21Db250ZXh0TWVudSA9IGN1c3RvbUNvbnRleHRNZW51ID8gY3VzdG9tQ29udGV4dE1lbnUudHJpbSgpIDogXCJcIjtcclxuICAgIGlmIChjdXN0b21Db250ZXh0TWVudSkge1xyXG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgbGV0IGN1c3RvbUNvbnRleHRNZW51RGF0YSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpLmdldFByb3BlcnR5VmFsdWUoXCItLWN1c3RvbS1jb250ZXh0bWVudS1kYXRhXCIpO1xyXG4gICAgICAgIG9wZW5Db250ZXh0TWVudShjdXN0b21Db250ZXh0TWVudSwgZXZlbnQuY2xpZW50WCwgZXZlbnQuY2xpZW50WSwgY3VzdG9tQ29udGV4dE1lbnVEYXRhKTtcclxuICAgICAgICByZXR1cm5cclxuICAgIH1cclxuXHJcbiAgICBwcm9jZXNzRGVmYXVsdENvbnRleHRNZW51KGV2ZW50KTtcclxufVxyXG5cclxuXHJcbi8qXHJcbi0tZGVmYXVsdC1jb250ZXh0bWVudTogYXV0bzsgKGRlZmF1bHQpIHdpbGwgc2hvdyB0aGUgZGVmYXVsdCBjb250ZXh0IG1lbnUgaWYgY29udGVudEVkaXRhYmxlIGlzIHRydWUgT1IgdGV4dCBoYXMgYmVlbiBzZWxlY3RlZCBPUiBlbGVtZW50IGlzIGlucHV0IG9yIHRleHRhcmVhXHJcbi0tZGVmYXVsdC1jb250ZXh0bWVudTogc2hvdzsgd2lsbCBhbHdheXMgc2hvdyB0aGUgZGVmYXVsdCBjb250ZXh0IG1lbnVcclxuLS1kZWZhdWx0LWNvbnRleHRtZW51OiBoaWRlOyB3aWxsIGFsd2F5cyBoaWRlIHRoZSBkZWZhdWx0IGNvbnRleHQgbWVudVxyXG5cclxuVGhpcyBydWxlIGlzIGluaGVyaXRlZCBsaWtlIG5vcm1hbCBDU1MgcnVsZXMsIHNvIG5lc3Rpbmcgd29ya3MgYXMgZXhwZWN0ZWRcclxuKi9cclxuZnVuY3Rpb24gcHJvY2Vzc0RlZmF1bHRDb250ZXh0TWVudShldmVudCkge1xyXG4gICAgLy8gRGVidWcgYnVpbGRzIGFsd2F5cyBzaG93IHRoZSBtZW51XHJcbiAgICBpZiAoREVCVUcpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUHJvY2VzcyBkZWZhdWx0IGNvbnRleHQgbWVudVxyXG4gICAgY29uc3QgZWxlbWVudCA9IGV2ZW50LnRhcmdldDtcclxuICAgIGNvbnN0IGNvbXB1dGVkU3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KTtcclxuICAgIGNvbnN0IGRlZmF1bHRDb250ZXh0TWVudUFjdGlvbiA9IGNvbXB1dGVkU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShcIi0tZGVmYXVsdC1jb250ZXh0bWVudVwiKS50cmltKCk7XHJcbiAgICBzd2l0Y2ggKGRlZmF1bHRDb250ZXh0TWVudUFjdGlvbikge1xyXG4gICAgICAgIGNhc2UgXCJzaG93XCI6XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICBjYXNlIFwiaGlkZVwiOlxyXG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgY29udGVudEVkaXRhYmxlIGlzIHRydWVcclxuICAgICAgICAgICAgaWYgKGVsZW1lbnQuaXNDb250ZW50RWRpdGFibGUpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGV4dCBoYXMgYmVlbiBzZWxlY3RlZFxyXG4gICAgICAgICAgICBjb25zdCBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IGhhc1NlbGVjdGlvbiA9IChzZWxlY3Rpb24udG9TdHJpbmcoKS5sZW5ndGggPiAwKVxyXG4gICAgICAgICAgICBpZiAoaGFzU2VsZWN0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNlbGVjdGlvbi5yYW5nZUNvdW50OyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCByYW5nZSA9IHNlbGVjdGlvbi5nZXRSYW5nZUF0KGkpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlY3RzID0gcmFuZ2UuZ2V0Q2xpZW50UmVjdHMoKTtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHJlY3RzLmxlbmd0aDsgaisrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlY3QgPSByZWN0c1tqXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQocmVjdC5sZWZ0LCByZWN0LnRvcCkgPT09IGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBDaGVjayBpZiB0YWduYW1lIGlzIGlucHV0IG9yIHRleHRhcmVhXHJcbiAgICAgICAgICAgIGlmIChlbGVtZW50LnRhZ05hbWUgPT09IFwiSU5QVVRcIiB8fCBlbGVtZW50LnRhZ05hbWUgPT09IFwiVEVYVEFSRUFcIikge1xyXG4gICAgICAgICAgICAgICAgaWYgKGhhc1NlbGVjdGlvbiB8fCAoIWVsZW1lbnQucmVhZE9ubHkgJiYgIWVsZW1lbnQuZGlzYWJsZWQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBoaWRlIGRlZmF1bHQgY29udGV4dCBtZW51XHJcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICB9XHJcbn1cclxuIiwgIlxyXG5pbXBvcnQge0VtaXQsIFdhaWxzRXZlbnR9IGZyb20gXCIuL2V2ZW50c1wiO1xyXG5pbXBvcnQge1F1ZXN0aW9ufSBmcm9tIFwiLi9kaWFsb2dzXCI7XHJcbmltcG9ydCB7V2luZG93TWV0aG9kcywgR2V0fSBmcm9tIFwiLi93aW5kb3dcIjtcclxuXHJcbi8qKlxyXG4gKiBTZW5kcyBhbiBldmVudCB3aXRoIHRoZSBnaXZlbiBuYW1lIGFuZCBvcHRpb25hbCBkYXRhLlxyXG4gKlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lIC0gVGhlIG5hbWUgb2YgdGhlIGV2ZW50IHRvIHNlbmQuXHJcbiAqIEBwYXJhbSB7YW55fSBbZGF0YT1udWxsXSAtIE9wdGlvbmFsIGRhdGEgdG8gc2VuZCBhbG9uZyB3aXRoIHRoZSBldmVudC5cclxuICpcclxuICogQHJldHVybiB7dm9pZH1cclxuICovXHJcbmZ1bmN0aW9uIHNlbmRFdmVudChldmVudE5hbWUsIGRhdGE9bnVsbCkge1xyXG4gICAgbGV0IGV2ZW50ID0gbmV3IFdhaWxzRXZlbnQoZXZlbnROYW1lLCBkYXRhKTtcclxuICAgIEVtaXQoZXZlbnQpO1xyXG59XHJcblxyXG4vKipcclxuICogQWRkcyBldmVudCBsaXN0ZW5lcnMgdG8gZWxlbWVudHMgd2l0aCBgd21sLWV2ZW50YCBhdHRyaWJ1dGUuXHJcbiAqXHJcbiAqIEByZXR1cm4ge3ZvaWR9XHJcbiAqL1xyXG5mdW5jdGlvbiBhZGRXTUxFdmVudExpc3RlbmVycygpIHtcclxuICAgIGNvbnN0IGVsZW1lbnRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW3dtbC1ldmVudF0nKTtcclxuICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICBjb25zdCBldmVudFR5cGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLWV2ZW50Jyk7XHJcbiAgICAgICAgY29uc3QgY29uZmlybSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd3bWwtY29uZmlybScpO1xyXG4gICAgICAgIGNvbnN0IHRyaWdnZXIgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLXRyaWdnZXInKSB8fCBcImNsaWNrXCI7XHJcblxyXG4gICAgICAgIGxldCBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKGNvbmZpcm0pIHtcclxuICAgICAgICAgICAgICAgIFF1ZXN0aW9uKHtUaXRsZTogXCJDb25maXJtXCIsIE1lc3NhZ2U6Y29uZmlybSwgRGV0YWNoZWQ6IGZhbHNlLCBCdXR0b25zOlt7TGFiZWw6XCJZZXNcIn0se0xhYmVsOlwiTm9cIiwgSXNEZWZhdWx0OnRydWV9XX0pLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT09IFwiTm9cIikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZW5kRXZlbnQoZXZlbnRUeXBlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBzZW5kRXZlbnQoZXZlbnRUeXBlKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvLyBSZW1vdmUgZXhpc3RpbmcgbGlzdGVuZXJzXHJcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKHRyaWdnZXIsIGNhbGxiYWNrKTtcclxuXHJcbiAgICAgICAgLy8gQWRkIG5ldyBsaXN0ZW5lclxyXG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcih0cmlnZ2VyLCBjYWxsYmFjayk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuLyoqXHJcbiAqIENhbGxzIGEgbWV0aG9kIG9uIHRoZSB3aW5kb3cgb2JqZWN0LlxyXG4gKlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kIC0gVGhlIG5hbWUgb2YgdGhlIG1ldGhvZCB0byBjYWxsIG9uIHRoZSB3aW5kb3cgb2JqZWN0LlxyXG4gKlxyXG4gKiBAcmV0dXJuIHt2b2lkfVxyXG4gKi9cclxuZnVuY3Rpb24gY2FsbFdpbmRvd01ldGhvZChtZXRob2QpIHtcclxuICAgIC8vIFRPRE86IE1ha2UgdGhpcyBhIHBhcmFtZXRlciFcclxuICAgIGxldCB3aW5kb3dOYW1lID0gJyc7XHJcbiAgICBsZXQgdGFyZ2V0V2luZG93ID0gR2V0KCcnKTtcclxuICAgIGxldCBtZXRob2RNYXAgPSBXaW5kb3dNZXRob2RzKHRhcmdldFdpbmRvdyk7XHJcbiAgICBpZiAoIW1ldGhvZE1hcC5oYXMobWV0aG9kKSkge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKFwiV2luZG93IG1ldGhvZCBcIiArIG1ldGhvZCArIFwiIG5vdCBmb3VuZFwiKTtcclxuICAgIH1cclxuICAgIG1ldGhvZE1hcC5nZXQobWV0aG9kKSgpO1xyXG59XHJcblxyXG4vKipcclxuICogQWRkcyB3aW5kb3cgbGlzdGVuZXJzIGZvciBlbGVtZW50cyB3aXRoIHRoZSAnd21sLXdpbmRvdycgYXR0cmlidXRlLlxyXG4gKiBSZW1vdmVzIGFueSBleGlzdGluZyBsaXN0ZW5lcnMgYmVmb3JlIGFkZGluZyBuZXcgb25lcy5cclxuICpcclxuICogQHJldHVybiB7dm9pZH1cclxuICovXHJcbmZ1bmN0aW9uIGFkZFdNTFdpbmRvd0xpc3RlbmVycygpIHtcclxuICAgIGNvbnN0IGVsZW1lbnRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW3dtbC13aW5kb3ddJyk7XHJcbiAgICBlbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgY29uc3Qgd2luZG93TWV0aG9kID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3dtbC13aW5kb3cnKTtcclxuICAgICAgICBjb25zdCBjb25maXJtID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3dtbC1jb25maXJtJyk7XHJcbiAgICAgICAgY29uc3QgdHJpZ2dlciA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd3bWwtdHJpZ2dlcicpIHx8IFwiY2xpY2tcIjtcclxuXHJcbiAgICAgICAgbGV0IGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAoY29uZmlybSkge1xyXG4gICAgICAgICAgICAgICAgUXVlc3Rpb24oe1RpdGxlOiBcIkNvbmZpcm1cIiwgTWVzc2FnZTpjb25maXJtLCBCdXR0b25zOlt7TGFiZWw6XCJZZXNcIn0se0xhYmVsOlwiTm9cIiwgSXNEZWZhdWx0OnRydWV9XX0pLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT09IFwiTm9cIikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYWxsV2luZG93TWV0aG9kKHdpbmRvd01ldGhvZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2FsbFdpbmRvd01ldGhvZCh3aW5kb3dNZXRob2QpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8vIFJlbW92ZSBleGlzdGluZyBsaXN0ZW5lcnNcclxuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIodHJpZ2dlciwgY2FsbGJhY2spO1xyXG5cclxuICAgICAgICAvLyBBZGQgbmV3IGxpc3RlbmVyXHJcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKHRyaWdnZXIsIGNhbGxiYWNrKTtcclxuICAgIH0pO1xyXG59XHJcblxyXG4vKipcclxuICogQWRkcyBhIGxpc3RlbmVyIHRvIGVsZW1lbnRzIHdpdGggdGhlICd3bWwtb3BlbnVybCcgYXR0cmlidXRlLlxyXG4gKiBXaGVuIHRoZSBzcGVjaWZpZWQgdHJpZ2dlciBldmVudCBpcyBmaXJlZCBvbiBhbnkgb2YgdGhlc2UgZWxlbWVudHMsXHJcbiAqIHRoZSBsaXN0ZW5lciB3aWxsIG9wZW4gdGhlIFVSTCBzcGVjaWZpZWQgYnkgdGhlICd3bWwtb3BlbnVybCcgYXR0cmlidXRlLlxyXG4gKiBJZiBhICd3bWwtY29uZmlybScgYXR0cmlidXRlIGlzIHByb3ZpZGVkLCBhIGNvbmZpcm1hdGlvbiBkaWFsb2cgd2lsbCBiZSBkaXNwbGF5ZWQsXHJcbiAqIGFuZCB0aGUgVVJMIHdpbGwgb25seSBiZSBvcGVuZWQgaWYgdGhlIHVzZXIgY29uZmlybXMuXHJcbiAqXHJcbiAqIEByZXR1cm4ge3ZvaWR9XHJcbiAqL1xyXG5mdW5jdGlvbiBhZGRXTUxPcGVuQnJvd3Nlckxpc3RlbmVyKCkge1xyXG4gICAgY29uc3QgZWxlbWVudHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdbd21sLW9wZW51cmxdJyk7XHJcbiAgICBlbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgY29uc3QgdXJsID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3dtbC1vcGVudXJsJyk7XHJcbiAgICAgICAgY29uc3QgY29uZmlybSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd3bWwtY29uZmlybScpO1xyXG4gICAgICAgIGNvbnN0IHRyaWdnZXIgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLXRyaWdnZXInKSB8fCBcImNsaWNrXCI7XHJcblxyXG4gICAgICAgIGxldCBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKGNvbmZpcm0pIHtcclxuICAgICAgICAgICAgICAgIFF1ZXN0aW9uKHtUaXRsZTogXCJDb25maXJtXCIsIE1lc3NhZ2U6Y29uZmlybSwgQnV0dG9uczpbe0xhYmVsOlwiWWVzXCJ9LHtMYWJlbDpcIk5vXCIsIElzRGVmYXVsdDp0cnVlfV19KS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAocmVzdWx0ICE9PSBcIk5vXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCB3YWlscy5Ccm93c2VyLk9wZW5VUkwodXJsKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2b2lkIHdhaWxzLkJyb3dzZXIuT3BlblVSTCh1cmwpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8vIFJlbW92ZSBleGlzdGluZyBsaXN0ZW5lcnNcclxuICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIodHJpZ2dlciwgY2FsbGJhY2spO1xyXG5cclxuICAgICAgICAvLyBBZGQgbmV3IGxpc3RlbmVyXHJcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKHRyaWdnZXIsIGNhbGxiYWNrKTtcclxuICAgIH0pO1xyXG59XHJcblxyXG4vKipcclxuICogUmVsb2FkcyB0aGUgV01MIHBhZ2UgYnkgYWRkaW5nIG5lY2Vzc2FyeSBldmVudCBsaXN0ZW5lcnMgYW5kIGJyb3dzZXIgbGlzdGVuZXJzLlxyXG4gKlxyXG4gKiBAcmV0dXJuIHt2b2lkfVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHJlbG9hZFdNTCgpIHtcclxuICAgIGNvbnNvbGUubG9nKFwiUmVsb2FkaW5nIFdNTFwiKTtcclxuICAgIGFkZFdNTEV2ZW50TGlzdGVuZXJzKCk7XHJcbiAgICBhZGRXTUxXaW5kb3dMaXN0ZW5lcnMoKTtcclxuICAgIGFkZFdNTE9wZW5Ccm93c2VyTGlzdGVuZXIoKTtcclxufVxyXG4iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuLyoganNoaW50IGVzdmVyc2lvbjogOSAqL1xyXG5cclxubGV0IGZsYWdzID0gbmV3IE1hcCgpO1xyXG5cclxuZnVuY3Rpb24gY29udmVydFRvTWFwKG9iaikge1xyXG4gICAgY29uc3QgbWFwID0gbmV3IE1hcCgpO1xyXG5cclxuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKG9iaikpIHtcclxuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICBtYXAuc2V0KGtleSwgY29udmVydFRvTWFwKHZhbHVlKSk7IC8vIFJlY3Vyc2l2ZWx5IGNvbnZlcnQgbmVzdGVkIG9iamVjdFxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIG1hcC5zZXQoa2V5LCB2YWx1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBtYXA7XHJcbn1cclxuXHJcbmZldGNoKFwiL3dhaWxzL2ZsYWdzXCIpLnRoZW4oKHJlc3BvbnNlKSA9PiB7XHJcbiAgICByZXNwb25zZS5qc29uKCkudGhlbigoZGF0YSkgPT4ge1xyXG4gICAgICAgIGZsYWdzID0gY29udmVydFRvTWFwKGRhdGEpO1xyXG4gICAgfSk7XHJcbn0pO1xyXG5cclxuXHJcbmZ1bmN0aW9uIGdldFZhbHVlRnJvbU1hcChrZXlTdHJpbmcpIHtcclxuICAgIGNvbnN0IGtleXMgPSBrZXlTdHJpbmcuc3BsaXQoJy4nKTtcclxuICAgIGxldCB2YWx1ZSA9IGZsYWdzO1xyXG5cclxuICAgIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcclxuICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBNYXApIHtcclxuICAgICAgICAgICAgdmFsdWUgPSB2YWx1ZS5nZXQoa2V5KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlW2tleV07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHZhbHVlO1xyXG59XHJcblxyXG4vKipcclxuICogUmV0cmlldmVzIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHNwZWNpZmllZCBrZXkgZnJvbSB0aGUgZmxhZyBtYXAuXHJcbiAqXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXlTdHJpbmcgLSBUaGUga2V5IHRvIHJldHJpZXZlIHRoZSB2YWx1ZSBmb3IuXHJcbiAqIEByZXR1cm4geyp9IC0gVGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3BlY2lmaWVkIGtleS5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBHZXRGbGFnKGtleVN0cmluZykge1xyXG4gICAgcmV0dXJuIGdldFZhbHVlRnJvbU1hcChrZXlTdHJpbmcpO1xyXG59XHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcblxyXG5pbXBvcnQge2ludm9rZSwgSXNXaW5kb3dzfSBmcm9tIFwiLi9zeXN0ZW1cIjtcclxuaW1wb3J0IHtHZXRGbGFnfSBmcm9tIFwiLi9mbGFnc1wiO1xyXG5cclxubGV0IHNob3VsZERyYWcgPSBmYWxzZTtcclxubGV0IHJlc2l6ZUVkZ2UgPSBudWxsO1xyXG5sZXQgcmVzaXphYmxlID0gZmFsc2U7XHJcbmxldCBkZWZhdWx0Q3Vyc29yID0gXCJhdXRvXCI7XHJcbndpbmRvdy5fd2FpbHMgPSB3aW5kb3cuX3dhaWxzIHx8IHt9O1xyXG53aW5kb3cuX3dhaWxzLnNldFJlc2l6YWJsZSA9IHNldFJlc2l6YWJsZTtcclxud2luZG93Ll93YWlscy5lbmREcmFnID0gZW5kRHJhZztcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBkcmFnVGVzdChlKSB7XHJcbiAgICBsZXQgdmFsID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZS50YXJnZXQpLmdldFByb3BlcnR5VmFsdWUoXCItLXdlYmtpdC1hcHAtcmVnaW9uXCIpO1xyXG4gICAgaWYgKHZhbCAmJiB2YWwudHJpbSgpICE9PSBcImRyYWdcIiB8fCBlLmJ1dHRvbnMgIT09IDEpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZS5kZXRhaWwgPT09IDE7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBzZXR1cERyYWcoKSB7XHJcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgb25Nb3VzZURvd24pO1xyXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIG9uTW91c2VNb3ZlKTtcclxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgb25Nb3VzZVVwKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHNldFJlc2l6YWJsZSh2YWx1ZSkge1xyXG4gICAgcmVzaXphYmxlID0gdmFsdWU7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBlbmREcmFnKCkge1xyXG4gICAgZG9jdW1lbnQuYm9keS5zdHlsZS5jdXJzb3IgPSAnZGVmYXVsdCc7XHJcbiAgICBzaG91bGREcmFnID0gZmFsc2U7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHRlc3RSZXNpemUoKSB7XHJcbiAgICBpZiggcmVzaXplRWRnZSApIHtcclxuICAgICAgICBpbnZva2UoYHJlc2l6ZToke3Jlc2l6ZUVkZ2V9YCk7XHJcbiAgICAgICAgcmV0dXJuIHRydWVcclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZTtcclxufVxyXG5cclxuZnVuY3Rpb24gb25Nb3VzZURvd24oZSkge1xyXG4gICAgaWYoSXNXaW5kb3dzKCkgJiYgdGVzdFJlc2l6ZSgpIHx8IGRyYWdUZXN0KGUpKSB7XHJcbiAgICAgICAgc2hvdWxkRHJhZyA9ICEhaXNWYWxpZERyYWcoZSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzVmFsaWREcmFnKGUpIHtcclxuICAgIC8vIElnbm9yZSBkcmFnIG9uIHNjcm9sbGJhcnNcclxuICAgIHJldHVybiAhKGUub2Zmc2V0WCA+IGUudGFyZ2V0LmNsaWVudFdpZHRoIHx8IGUub2Zmc2V0WSA+IGUudGFyZ2V0LmNsaWVudEhlaWdodCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIG9uTW91c2VVcChlKSB7XHJcbiAgICBsZXQgbW91c2VQcmVzc2VkID0gZS5idXR0b25zICE9PSB1bmRlZmluZWQgPyBlLmJ1dHRvbnMgOiBlLndoaWNoO1xyXG4gICAgaWYgKG1vdXNlUHJlc3NlZCA+IDApIHtcclxuICAgICAgICBlbmREcmFnKCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNldFJlc2l6ZShjdXJzb3IgPSBkZWZhdWx0Q3Vyc29yKSB7XHJcbiAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUuY3Vyc29yID0gY3Vyc29yO1xyXG4gICAgcmVzaXplRWRnZSA9IGN1cnNvcjtcclxufVxyXG5cclxuZnVuY3Rpb24gb25Nb3VzZU1vdmUoZSkge1xyXG4gICAgc2hvdWxkRHJhZyA9IGNoZWNrRHJhZyhlKTtcclxuICAgIGlmIChJc1dpbmRvd3MoKSAmJiByZXNpemFibGUpIHtcclxuICAgICAgICBoYW5kbGVSZXNpemUoZSk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNoZWNrRHJhZyhlKSB7XHJcbiAgICBsZXQgbW91c2VQcmVzc2VkID0gZS5idXR0b25zICE9PSB1bmRlZmluZWQgPyBlLmJ1dHRvbnMgOiBlLndoaWNoO1xyXG4gICAgaWYoc2hvdWxkRHJhZyAmJiBtb3VzZVByZXNzZWQgPiAwKSB7XHJcbiAgICAgICAgaW52b2tlKFwiZHJhZ1wiKTtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gc2hvdWxkRHJhZztcclxufVxyXG5cclxuZnVuY3Rpb24gaGFuZGxlUmVzaXplKGUpIHtcclxuICAgIGxldCByZXNpemVIYW5kbGVIZWlnaHQgPSBHZXRGbGFnKFwic3lzdGVtLnJlc2l6ZUhhbmRsZUhlaWdodFwiKSB8fCA1O1xyXG4gICAgbGV0IHJlc2l6ZUhhbmRsZVdpZHRoID0gR2V0RmxhZyhcInN5c3RlbS5yZXNpemVIYW5kbGVXaWR0aFwiKSB8fCA1O1xyXG5cclxuICAgIC8vIEV4dHJhIHBpeGVscyBmb3IgdGhlIGNvcm5lciBhcmVhc1xyXG4gICAgbGV0IGNvcm5lckV4dHJhID0gR2V0RmxhZyhcInJlc2l6ZUNvcm5lckV4dHJhXCIpIHx8IDEwO1xyXG5cclxuICAgIGxldCByaWdodEJvcmRlciA9IHdpbmRvdy5vdXRlcldpZHRoIC0gZS5jbGllbnRYIDwgcmVzaXplSGFuZGxlV2lkdGg7XHJcbiAgICBsZXQgbGVmdEJvcmRlciA9IGUuY2xpZW50WCA8IHJlc2l6ZUhhbmRsZVdpZHRoO1xyXG4gICAgbGV0IHRvcEJvcmRlciA9IGUuY2xpZW50WSA8IHJlc2l6ZUhhbmRsZUhlaWdodDtcclxuICAgIGxldCBib3R0b21Cb3JkZXIgPSB3aW5kb3cub3V0ZXJIZWlnaHQgLSBlLmNsaWVudFkgPCByZXNpemVIYW5kbGVIZWlnaHQ7XHJcblxyXG4gICAgLy8gQWRqdXN0IGZvciBjb3JuZXJzXHJcbiAgICBsZXQgcmlnaHRDb3JuZXIgPSB3aW5kb3cub3V0ZXJXaWR0aCAtIGUuY2xpZW50WCA8IChyZXNpemVIYW5kbGVXaWR0aCArIGNvcm5lckV4dHJhKTtcclxuICAgIGxldCBsZWZ0Q29ybmVyID0gZS5jbGllbnRYIDwgKHJlc2l6ZUhhbmRsZVdpZHRoICsgY29ybmVyRXh0cmEpO1xyXG4gICAgbGV0IHRvcENvcm5lciA9IGUuY2xpZW50WSA8IChyZXNpemVIYW5kbGVIZWlnaHQgKyBjb3JuZXJFeHRyYSk7XHJcbiAgICBsZXQgYm90dG9tQ29ybmVyID0gd2luZG93Lm91dGVySGVpZ2h0IC0gZS5jbGllbnRZIDwgKHJlc2l6ZUhhbmRsZUhlaWdodCArIGNvcm5lckV4dHJhKTtcclxuXHJcbiAgICAvLyBJZiB3ZSBhcmVuJ3Qgb24gYW4gZWRnZSwgYnV0IHdlcmUsIHJlc2V0IHRoZSBjdXJzb3IgdG8gZGVmYXVsdFxyXG4gICAgaWYgKCFsZWZ0Qm9yZGVyICYmICFyaWdodEJvcmRlciAmJiAhdG9wQm9yZGVyICYmICFib3R0b21Cb3JkZXIgJiYgcmVzaXplRWRnZSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgc2V0UmVzaXplKCk7XHJcbiAgICB9XHJcbiAgICAvLyBBZGp1c3RlZCBmb3IgY29ybmVyIGFyZWFzXHJcbiAgICBlbHNlIGlmIChyaWdodENvcm5lciAmJiBib3R0b21Db3JuZXIpIHNldFJlc2l6ZShcInNlLXJlc2l6ZVwiKTtcclxuICAgIGVsc2UgaWYgKGxlZnRDb3JuZXIgJiYgYm90dG9tQ29ybmVyKSBzZXRSZXNpemUoXCJzdy1yZXNpemVcIik7XHJcbiAgICBlbHNlIGlmIChsZWZ0Q29ybmVyICYmIHRvcENvcm5lcikgc2V0UmVzaXplKFwibnctcmVzaXplXCIpO1xyXG4gICAgZWxzZSBpZiAodG9wQ29ybmVyICYmIHJpZ2h0Q29ybmVyKSBzZXRSZXNpemUoXCJuZS1yZXNpemVcIik7XHJcbiAgICBlbHNlIGlmIChsZWZ0Qm9yZGVyKSBzZXRSZXNpemUoXCJ3LXJlc2l6ZVwiKTtcclxuICAgIGVsc2UgaWYgKHRvcEJvcmRlcikgc2V0UmVzaXplKFwibi1yZXNpemVcIik7XHJcbiAgICBlbHNlIGlmIChib3R0b21Cb3JkZXIpIHNldFJlc2l6ZShcInMtcmVzaXplXCIpO1xyXG4gICAgZWxzZSBpZiAocmlnaHRCb3JkZXIpIHNldFJlc2l6ZShcImUtcmVzaXplXCIpO1xyXG59XHJcbiIsICIvKlxyXG4gXyAgICAgX18gICAgIF8gX19cclxufCB8ICAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcblxyXG5pbXBvcnQgKiBhcyBDbGlwYm9hcmQgZnJvbSAnLi9Ad2FpbHNpby9ydW50aW1lL2NsaXBib2FyZCc7XHJcbmltcG9ydCAqIGFzIEFwcGxpY2F0aW9uIGZyb20gJy4vQHdhaWxzaW8vcnVudGltZS9hcHBsaWNhdGlvbic7XHJcbmltcG9ydCAqIGFzIFNjcmVlbnMgZnJvbSAnLi9Ad2FpbHNpby9ydW50aW1lL3NjcmVlbnMnO1xyXG5pbXBvcnQgKiBhcyBTeXN0ZW0gZnJvbSAnLi9Ad2FpbHNpby9ydW50aW1lL3N5c3RlbSc7XHJcbmltcG9ydCAqIGFzIEJyb3dzZXIgZnJvbSAnLi9Ad2FpbHNpby9ydW50aW1lL2Jyb3dzZXInO1xyXG5pbXBvcnQgKiBhcyBXaW5kb3cgZnJvbSAnLi9Ad2FpbHNpby9ydW50aW1lL3dpbmRvdyc7XHJcbmltcG9ydCB7UGx1Z2luLCBDYWxsLCBlcnJvckhhbmRsZXIgYXMgY2FsbEVycm9ySGFuZGxlciwgcmVzdWx0SGFuZGxlciBhcyBjYWxsUmVzdWx0SGFuZGxlciwgQnlJRCwgQnlOYW1lfSBmcm9tIFwiLi9Ad2FpbHNpby9ydW50aW1lL2NhbGxzXCI7XHJcbmltcG9ydCB7Y2xpZW50SWR9IGZyb20gJy4vQHdhaWxzaW8vcnVudGltZS9ydW50aW1lJztcclxuaW1wb3J0IHtkaXNwYXRjaFdhaWxzRXZlbnQsIEVtaXQsIE9mZiwgT2ZmQWxsLCBPbiwgT25jZSwgT25NdWx0aXBsZX0gZnJvbSBcIi4vQHdhaWxzaW8vcnVudGltZS9ldmVudHNcIjtcclxuaW1wb3J0IHtkaWFsb2dDYWxsYmFjaywgZGlhbG9nRXJyb3JDYWxsYmFjaywgRXJyb3IsIEluZm8sIE9wZW5GaWxlLCBRdWVzdGlvbiwgU2F2ZUZpbGUsIFdhcm5pbmd9IGZyb20gXCIuL0B3YWlsc2lvL3J1bnRpbWUvZGlhbG9nc1wiO1xyXG5pbXBvcnQge3NldHVwQ29udGV4dE1lbnVzfSBmcm9tICcuL0B3YWlsc2lvL3J1bnRpbWUvY29udGV4dG1lbnUnO1xyXG5pbXBvcnQge3JlbG9hZFdNTH0gZnJvbSAnLi9Ad2FpbHNpby9ydW50aW1lL3dtbCc7XHJcbmltcG9ydCB7c2V0dXBEcmFnLCBlbmREcmFnLCBzZXRSZXNpemFibGV9IGZyb20gJy4vQHdhaWxzaW8vcnVudGltZS9kcmFnJztcclxuXHJcbndpbmRvdy53YWlscyA9IHtcclxuICAgIC4uLm5ld1J1bnRpbWUobnVsbCksXHJcbiAgICBjbGllbnRJZDogY2xpZW50SWQsXHJcbn07XHJcblxyXG4vLyBJbnRlcm5hbCB3YWlscyBlbmRwb2ludHNcclxud2luZG93Ll93YWlscyA9IHtcclxuICAgIGRpYWxvZ0NhbGxiYWNrLFxyXG4gICAgZGlhbG9nRXJyb3JDYWxsYmFjayxcclxuICAgIGRpc3BhdGNoV2FpbHNFdmVudCxcclxuICAgIGNhbGxFcnJvckhhbmRsZXIsXHJcbiAgICBjYWxsUmVzdWx0SGFuZGxlcixcclxuICAgIGVuZERyYWcsXHJcbiAgICBzZXRSZXNpemFibGUsXHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbmV3UnVudGltZSh3aW5kb3dOYW1lKSB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIENsaXBib2FyZDoge1xyXG4gICAgICAgICAgICAuLi5DbGlwYm9hcmRcclxuICAgICAgICB9LFxyXG4gICAgICAgIEFwcGxpY2F0aW9uOiB7XHJcbiAgICAgICAgICAgIC4uLkFwcGxpY2F0aW9uLFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgU3lzdGVtLFxyXG4gICAgICAgIFNjcmVlbnMsXHJcbiAgICAgICAgQnJvd3NlcixcclxuICAgICAgICBDYWxsOiB7XHJcbiAgICAgICAgICAgIENhbGwsXHJcbiAgICAgICAgICAgIEJ5SUQsXHJcbiAgICAgICAgICAgIEJ5TmFtZSxcclxuICAgICAgICAgICAgUGx1Z2luLFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgV01MOiB7XHJcbiAgICAgICAgICAgIFJlbG9hZDogcmVsb2FkV01MLFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgRGlhbG9nOiB7XHJcbiAgICAgICAgICAgIEluZm8sXHJcbiAgICAgICAgICAgIFdhcm5pbmcsXHJcbiAgICAgICAgICAgIEVycm9yLFxyXG4gICAgICAgICAgICBRdWVzdGlvbixcclxuICAgICAgICAgICAgT3BlbkZpbGUsXHJcbiAgICAgICAgICAgIFNhdmVGaWxlLFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgRXZlbnRzOiB7XHJcbiAgICAgICAgICAgIEVtaXQsXHJcbiAgICAgICAgICAgIE9uLFxyXG4gICAgICAgICAgICBPbmNlLFxyXG4gICAgICAgICAgICBPbk11bHRpcGxlLFxyXG4gICAgICAgICAgICBPZmYsXHJcbiAgICAgICAgICAgIE9mZkFsbCxcclxuICAgICAgICB9LFxyXG4gICAgICAgIFdpbmRvdzoge1xyXG4gICAgICAgICAgICAuLi5XaW5kb3cuR2V0KCcnKVxyXG4gICAgICAgIH0sXHJcbiAgICB9O1xyXG59XHJcblxyXG5zZXR1cENvbnRleHRNZW51cygpO1xyXG5zZXR1cERyYWcoKTtcclxuXHJcbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIs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LGNBQWM7QUFBVyxnQkFBVSxXQUFXO0FBQUEsYUFDOUMsYUFBYTtBQUFhLGdCQUFVLFdBQVc7QUFBQSxhQUMvQztBQUFZLGdCQUFVLFVBQVU7QUFBQSxhQUNoQztBQUFXLGdCQUFVLFVBQVU7QUFBQSxhQUMvQjtBQUFjLGdCQUFVLFVBQVU7QUFBQSxhQUNsQztBQUFhLGdCQUFVLFVBQVU7QUFBQSxFQUM5Qzs7O0FDbEdBLFNBQU8sUUFBUTtBQUFBLElBQ1gsR0FBRyxXQUFXLElBQUk7QUFBQSxJQUNsQjtBQUFBLEVBQ0o7QUFHQSxTQUFPLFNBQVM7QUFBQSxJQUNaO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBLGNBQUFDO0FBQUEsRUFDSjtBQUVPLFdBQVMsV0FBVyxZQUFZO0FBQ25DLFdBQU87QUFBQSxNQUNILFdBQVc7QUFBQSxRQUNQLEdBQUc7QUFBQSxNQUNQO0FBQUEsTUFDQSxhQUFhO0FBQUEsUUFDVCxHQUFHO0FBQUEsTUFDUDtBQUFBLE1BQ0E7QUFBQSxNQUNBO0FBQUEsTUFDQTtBQUFBLE1BQ0EsTUFBTTtBQUFBLFFBQ0Y7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxNQUNKO0FBQUEsTUFDQSxLQUFLO0FBQUEsUUFDRCxRQUFRO0FBQUEsTUFDWjtBQUFBLE1BQ0EsUUFBUTtBQUFBLFFBQ0o7QUFBQSxRQUNBO0FBQUEsUUFDQSxPQUFBQztBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLE1BQ0o7QUFBQSxNQUNBLFFBQVE7QUFBQSxRQUNKO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxNQUNKO0FBQUEsTUFDQSxRQUFRO0FBQUEsUUFDSixHQUFVLElBQUksRUFBRTtBQUFBLE1BQ3BCO0FBQUEsSUFDSjtBQUFBLEVBQ0o7QUFFQSxvQkFBa0I7QUFDbEIsWUFBVTtBQUVWLFdBQVMsaUJBQWlCLG9CQUFvQixXQUFXO0FBQ3JELGNBQVU7QUFBQSxFQUNkLENBQUM7IiwKICAibmFtZXMiOiBbInNpemUiLCAiY2FsbCIsICJjYWxsIiwgImNhbGwiLCAiY2FsbCIsICJjYWxsIiwgIndpZHRoIiwgImhlaWdodCIsICJyZXNpemFibGUiLCAiY2FsbCIsICJjYWxsIiwgImV2ZW50TmFtZSIsICJjYWxsIiwgImdlbmVyYXRlSUQiLCAiRXJyb3IiLCAiY2FsbCIsICJzZXRSZXNpemFibGUiLCAic2V0UmVzaXphYmxlIiwgIkVycm9yIl0KfQo= diff --git a/v3/internal/runtime/runtime_debug_darwin.go b/v3/internal/runtime/runtime_debug_darwin.go deleted file mode 100644 index 14656126ffc..00000000000 --- a/v3/internal/runtime/runtime_debug_darwin.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build darwin && !production - -package runtime - -import _ "embed" - -//go:embed runtime_debug_desktop_darwin.js -var DesktopRuntime []byte diff --git a/v3/internal/runtime/runtime_debug_desktop_darwin.js b/v3/internal/runtime/runtime_debug_desktop_darwin.js deleted file mode 100644 index 3e0861b89b2..00000000000 --- a/v3/internal/runtime/runtime_debug_desktop_darwin.js +++ /dev/null @@ -1,873 +0,0 @@ -(() => { - var __defProp = Object.defineProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - - // desktop/clipboard.js - var clipboard_exports = {}; - __export(clipboard_exports, { - SetText: () => SetText, - Text: () => Text - }); - - // node_modules/nanoid/non-secure/index.js - var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"; - var nanoid = (size = 21) => { - let id = ""; - let i = size; - while (i--) { - id += urlAlphabet[Math.random() * 64 | 0]; - } - return id; - }; - - // desktop/runtime.js - var runtimeURL = window.location.origin + "/wails/runtime"; - var objectNames = { - Call: 0, - Clipboard: 1, - Application: 2, - Events: 3, - ContextMenu: 4, - Dialog: 5, - Window: 6, - Screens: 7, - System: 8, - Browser: 9 - }; - var clientId = nanoid(); - function runtimeCallWithID(objectID, method, windowName, args) { - let url = new URL(runtimeURL); - url.searchParams.append("object", objectID); - url.searchParams.append("method", method); - let fetchOptions = { - headers: {} - }; - if (windowName) { - fetchOptions.headers["x-wails-window-name"] = windowName; - } - if (args) { - url.searchParams.append("args", JSON.stringify(args)); - } - fetchOptions.headers["x-wails-client-id"] = clientId; - return new Promise((resolve, reject) => { - fetch(url, fetchOptions).then((response) => { - if (response.ok) { - if (response.headers.get("Content-Type") && response.headers.get("Content-Type").indexOf("application/json") !== -1) { - return response.json(); - } else { - return response.text(); - } - } - reject(Error(response.statusText)); - }).then((data) => resolve(data)).catch((error) => reject(error)); - }); - } - function newRuntimeCallerWithID(object, windowName) { - return function(method, args = null) { - return runtimeCallWithID(object, method, windowName, args); - }; - } - - // desktop/clipboard.js - var call = newRuntimeCallerWithID(objectNames.Clipboard); - var ClipboardSetText = 0; - var ClipboardText = 1; - function SetText(text) { - void call(ClipboardSetText, { text }); - } - function Text() { - return call(ClipboardText); - } - - // desktop/application.js - var application_exports = {}; - __export(application_exports, { - Hide: () => Hide, - Quit: () => Quit, - Show: () => Show - }); - var call2 = newRuntimeCallerWithID(objectNames.Application); - var methods = { - Hide: 0, - Show: 1, - Quit: 2 - }; - function Hide() { - void call2(methods.Hide); - } - function Show() { - void call2(methods.Show); - } - function Quit() { - void call2(methods.Quit); - } - - // desktop/screens.js - var screens_exports = {}; - __export(screens_exports, { - GetAll: () => GetAll, - GetCurrent: () => GetCurrent, - GetPrimary: () => GetPrimary - }); - var call3 = newRuntimeCallerWithID(objectNames.Screens); - var ScreensGetAll = 0; - var ScreensGetPrimary = 1; - var ScreensGetCurrent = 2; - function GetAll() { - return call3(ScreensGetAll); - } - function GetPrimary() { - return call3(ScreensGetPrimary); - } - function GetCurrent() { - return call3(ScreensGetCurrent); - } - - // desktop/system.js - var system_exports = {}; - __export(system_exports, { - IsDarkMode: () => IsDarkMode - }); - var call4 = newRuntimeCallerWithID(objectNames.System); - var SystemIsDarkMode = 0; - function IsDarkMode() { - return call4(SystemIsDarkMode); - } - - // desktop/browser.js - var browser_exports = {}; - __export(browser_exports, { - OpenURL: () => OpenURL - }); - var call5 = newRuntimeCallerWithID(objectNames.Browser); - var BrowserOpenURL = 0; - function OpenURL(url) { - void call5(BrowserOpenURL, { url }); - } - - // desktop/calls.js - var call6 = newRuntimeCallerWithID(objectNames.Call); - var CallBinding = 0; - var callResponses = /* @__PURE__ */ new Map(); - function generateID() { - let result; - do { - result = nanoid(); - } while (callResponses.has(result)); - return result; - } - function callCallback(id, data, isJSON) { - let p = callResponses.get(id); - if (p) { - if (isJSON) { - p.resolve(JSON.parse(data)); - } else { - p.resolve(data); - } - callResponses.delete(id); - } - } - function callErrorCallback(id, message) { - let p = callResponses.get(id); - if (p) { - p.reject(message); - callResponses.delete(id); - } - } - function callBinding(type, options) { - return new Promise((resolve, reject) => { - let id = generateID(); - options = options || {}; - options["call-id"] = id; - callResponses.set(id, { resolve, reject }); - call6(type, options).catch((error) => { - reject(error); - callResponses.delete(id); - }); - }); - } - function Call(options) { - return callBinding(CallBinding, options); - } - function CallByName(name, ...args) { - if (typeof name !== "string" || name.split(".").length !== 3) { - throw new Error("CallByName requires a string in the format 'package.struct.method'"); - } - let parts = name.split("."); - return callBinding(CallBinding, { - packageName: parts[0], - structName: parts[1], - methodName: parts[2], - args - }); - } - function CallByID(methodID, ...args) { - return callBinding(CallBinding, { - methodID, - args - }); - } - function Plugin(pluginName, methodName, ...args) { - return callBinding(CallBinding, { - packageName: "wails-plugins", - structName: pluginName, - methodName, - args - }); - } - - // desktop/window.js - var WindowCenter = 0; - var WindowSetTitle = 1; - var WindowFullscreen = 2; - var WindowUnFullscreen = 3; - var WindowSetSize = 4; - var WindowSize = 5; - var WindowSetMaxSize = 6; - var WindowSetMinSize = 7; - var WindowSetAlwaysOnTop = 8; - var WindowSetRelativePosition = 9; - var WindowRelativePosition = 10; - var WindowScreen = 11; - var WindowHide = 12; - var WindowMaximise = 13; - var WindowUnMaximise = 14; - var WindowToggleMaximise = 15; - var WindowMinimise = 16; - var WindowUnMinimise = 17; - var WindowRestore = 18; - var WindowShow = 19; - var WindowClose = 20; - var WindowSetBackgroundColour = 21; - var WindowSetResizable = 22; - var WindowWidth = 23; - var WindowHeight = 24; - var WindowZoomIn = 25; - var WindowZoomOut = 26; - var WindowZoomReset = 27; - var WindowGetZoomLevel = 28; - var WindowSetZoomLevel = 29; - function newWindow(windowName) { - let call10 = newRuntimeCallerWithID(objectNames.Window, windowName); - return { - /** - * Centers the window. - */ - Center: () => void call10(WindowCenter), - /** - * Set the window title. - * @param title - */ - SetTitle: (title) => void call10(WindowSetTitle, { title }), - /** - * Makes the window fullscreen. - */ - Fullscreen: () => void call10(WindowFullscreen), - /** - * Unfullscreen the window. - */ - UnFullscreen: () => void call10(WindowUnFullscreen), - /** - * Set the window size. - * @param {number} width The window width - * @param {number} height The window height - */ - SetSize: (width, height) => call10(WindowSetSize, { width, height }), - /** - * Get the window size. - * @returns {Promise} The window size - */ - Size: () => { - return call10(WindowSize); - }, - /** - * Set the window maximum size. - * @param {number} width - * @param {number} height - */ - SetMaxSize: (width, height) => void call10(WindowSetMaxSize, { width, height }), - /** - * Set the window minimum size. - * @param {number} width - * @param {number} height - */ - SetMinSize: (width, height) => void call10(WindowSetMinSize, { width, height }), - /** - * Set window to be always on top. - * @param {boolean} onTop Whether the window should be always on top - */ - SetAlwaysOnTop: (onTop) => void call10(WindowSetAlwaysOnTop, { alwaysOnTop: onTop }), - /** - * Set the window relative position. - * @param {number} x - * @param {number} y - */ - SetRelativePosition: (x, y) => call10(WindowSetRelativePosition, { x, y }), - /** - * Get the window position. - * @returns {Promise} The window position - */ - RelativePosition: () => { - return call10(WindowRelativePosition); - }, - /** - * Get the screen the window is on. - * @returns {Promise} - */ - Screen: () => { - return call10(WindowScreen); - }, - /** - * Hide the window - */ - Hide: () => void call10(WindowHide), - /** - * Maximise the window - */ - Maximise: () => void call10(WindowMaximise), - /** - * Show the window - */ - Show: () => void call10(WindowShow), - /** - * Close the window - */ - Close: () => void call10(WindowClose), - /** - * Toggle the window maximise state - */ - ToggleMaximise: () => void call10(WindowToggleMaximise), - /** - * Unmaximise the window - */ - UnMaximise: () => void call10(WindowUnMaximise), - /** - * Minimise the window - */ - Minimise: () => void call10(WindowMinimise), - /** - * Unminimise the window - */ - UnMinimise: () => void call10(WindowUnMinimise), - /** - * Restore the window - */ - Restore: () => void call10(WindowRestore), - /** - * Set the background colour of the window. - * @param {number} r - A value between 0 and 255 - * @param {number} g - A value between 0 and 255 - * @param {number} b - A value between 0 and 255 - * @param {number} a - A value between 0 and 255 - */ - SetBackgroundColour: (r, g, b, a) => void call10(WindowSetBackgroundColour, { r, g, b, a }), - /** - * Set whether the window can be resized or not - * @param {boolean} resizable - */ - SetResizable: (resizable2) => void call10(WindowSetResizable, { resizable: resizable2 }), - /** - * Get the window width - * @returns {Promise} - */ - Width: () => { - return call10(WindowWidth); - }, - /** - * Get the window height - * @returns {Promise} - */ - Height: () => { - return call10(WindowHeight); - }, - /** - * Zoom in the window - */ - ZoomIn: () => void call10(WindowZoomIn), - /** - * Zoom out the window - */ - ZoomOut: () => void call10(WindowZoomOut), - /** - * Reset the window zoom - */ - ZoomReset: () => void call10(WindowZoomReset), - /** - * Get the window zoom - * @returns {Promise} - */ - GetZoomLevel: () => { - return call10(WindowGetZoomLevel); - }, - /** - * Set the window zoom level - * @param {number} zoomLevel - */ - SetZoomLevel: (zoomLevel) => void call10(WindowSetZoomLevel, { zoomLevel }) - }; - } - - // desktop/events.js - var call7 = newRuntimeCallerWithID(objectNames.Events); - var EventEmit = 0; - var Listener = class { - /** - * Creates an instance of Listener. - * @param {string} eventName - * @param {function} callback - * @param {number} maxCallbacks - * @memberof Listener - */ - constructor(eventName, callback, maxCallbacks) { - this.eventName = eventName; - this.maxCallbacks = maxCallbacks || -1; - this.Callback = (data) => { - callback(data); - if (this.maxCallbacks === -1) { - return false; - } - this.maxCallbacks -= 1; - return this.maxCallbacks === 0; - }; - } - }; - var WailsEvent = class { - /** - * Creates an instance of WailsEvent. - * @param {string} name - Name of the event - * @param {any=null} data - Data associated with the event - * @memberof WailsEvent - */ - constructor(name, data = null) { - this.name = name; - this.data = data; - } - }; - var eventListeners = /* @__PURE__ */ new Map(); - function OnMultiple(eventName, callback, maxCallbacks) { - let listeners = eventListeners.get(eventName) || []; - const thisListener = new Listener(eventName, callback, maxCallbacks); - listeners.push(thisListener); - eventListeners.set(eventName, listeners); - return () => listenerOff(thisListener); - } - function On(eventName, callback) { - return OnMultiple(eventName, callback, -1); - } - function Once(eventName, callback) { - return OnMultiple(eventName, callback, 1); - } - function listenerOff(listener) { - const eventName = listener.eventName; - let listeners = eventListeners.get(eventName).filter((l) => l !== listener); - if (listeners.length === 0) { - eventListeners.delete(eventName); - } else { - eventListeners.set(eventName, listeners); - } - } - function dispatchWailsEvent(event) { - let listeners = eventListeners.get(event.name); - if (listeners) { - let toRemove = []; - listeners.forEach((listener) => { - let remove = listener.Callback(event); - if (remove) { - toRemove.push(listener); - } - }); - if (toRemove.length > 0) { - listeners = listeners.filter((l) => !toRemove.includes(l)); - if (listeners.length === 0) { - eventListeners.delete(event.name); - } else { - eventListeners.set(event.name, listeners); - } - } - } - } - function Off(eventName, ...additionalEventNames) { - let eventsToRemove = [eventName, ...additionalEventNames]; - eventsToRemove.forEach((eventName2) => { - eventListeners.delete(eventName2); - }); - } - function OffAll() { - eventListeners.clear(); - } - function Emit(event) { - void call7(EventEmit, event); - } - - // desktop/dialogs.js - var call8 = newRuntimeCallerWithID(objectNames.Dialog); - var DialogInfo = 0; - var DialogWarning = 1; - var DialogError = 2; - var DialogQuestion = 3; - var DialogOpenFile = 4; - var DialogSaveFile = 5; - var dialogResponses = /* @__PURE__ */ new Map(); - function generateID2() { - let result; - do { - result = nanoid(); - } while (dialogResponses.has(result)); - return result; - } - function dialogCallback(id, data, isJSON) { - let p = dialogResponses.get(id); - if (p) { - if (isJSON) { - p.resolve(JSON.parse(data)); - } else { - p.resolve(data); - } - dialogResponses.delete(id); - } - } - function dialogErrorCallback(id, message) { - let p = dialogResponses.get(id); - if (p) { - p.reject(message); - dialogResponses.delete(id); - } - } - function dialog(type, options) { - return new Promise((resolve, reject) => { - let id = generateID2(); - options = options || {}; - options["dialog-id"] = id; - dialogResponses.set(id, { resolve, reject }); - call8(type, options).catch((error) => { - reject(error); - dialogResponses.delete(id); - }); - }); - } - function Info(options) { - return dialog(DialogInfo, options); - } - function Warning(options) { - return dialog(DialogWarning, options); - } - function Error2(options) { - return dialog(DialogError, options); - } - function Question(options) { - return dialog(DialogQuestion, options); - } - function OpenFile(options) { - return dialog(DialogOpenFile, options); - } - function SaveFile(options) { - return dialog(DialogSaveFile, options); - } - - // desktop/contextmenu.js - var call9 = newRuntimeCallerWithID(objectNames.ContextMenu); - var ContextMenuOpen = 0; - function openContextMenu(id, x, y, data) { - void call9(ContextMenuOpen, { id, x, y, data }); - } - function setupContextMenus() { - window.addEventListener("contextmenu", contextMenuHandler); - } - function contextMenuHandler(event) { - let element = event.target; - let customContextMenu = window.getComputedStyle(element).getPropertyValue("--custom-contextmenu"); - customContextMenu = customContextMenu ? customContextMenu.trim() : ""; - if (customContextMenu) { - event.preventDefault(); - let customContextMenuData = window.getComputedStyle(element).getPropertyValue("--custom-contextmenu-data"); - openContextMenu(customContextMenu, event.clientX, event.clientY, customContextMenuData); - return; - } - processDefaultContextMenu(event); - } - function processDefaultContextMenu(event) { - if (true) { - return; - } - const element = event.target; - const computedStyle = window.getComputedStyle(element); - const defaultContextMenuAction = computedStyle.getPropertyValue("--default-contextmenu").trim(); - switch (defaultContextMenuAction) { - case "show": - return; - case "hide": - event.preventDefault(); - return; - default: - if (element.isContentEditable) { - return; - } - const selection = window.getSelection(); - const hasSelection = selection.toString().length > 0; - if (hasSelection) { - for (let i = 0; i < selection.rangeCount; i++) { - const range = selection.getRangeAt(i); - const rects = range.getClientRects(); - for (let j = 0; j < rects.length; j++) { - const rect = rects[j]; - if (document.elementFromPoint(rect.left, rect.top) === element) { - return; - } - } - } - } - if (element.tagName === "INPUT" || element.tagName === "TEXTAREA") { - if (hasSelection || !element.readOnly && !element.disabled) { - return; - } - } - event.preventDefault(); - } - } - - // desktop/wml.js - function sendEvent(eventName, data = null) { - let event = new WailsEvent(eventName, data); - Emit(event); - } - function addWMLEventListeners() { - const elements = document.querySelectorAll("[wml-event]"); - elements.forEach(function(element) { - const eventType = element.getAttribute("wml-event"); - const confirm = element.getAttribute("wml-confirm"); - const trigger = element.getAttribute("wml-trigger") || "click"; - let callback = function() { - if (confirm) { - Question({ Title: "Confirm", Message: confirm, Detached: false, Buttons: [{ Label: "Yes" }, { Label: "No", IsDefault: true }] }).then(function(result) { - if (result !== "No") { - sendEvent(eventType); - } - }); - return; - } - sendEvent(eventType); - }; - element.removeEventListener(trigger, callback); - element.addEventListener(trigger, callback); - }); - } - function callWindowMethod(method) { - if (wails.Window[method] === void 0) { - console.log("Window method " + method + " not found"); - } - wails.Window[method](); - } - function addWMLWindowListeners() { - const elements = document.querySelectorAll("[wml-window]"); - elements.forEach(function(element) { - const windowMethod = element.getAttribute("wml-window"); - const confirm = element.getAttribute("wml-confirm"); - const trigger = element.getAttribute("wml-trigger") || "click"; - let callback = function() { - if (confirm) { - Question({ Title: "Confirm", Message: confirm, Buttons: [{ Label: "Yes" }, { Label: "No", IsDefault: true }] }).then(function(result) { - if (result !== "No") { - callWindowMethod(windowMethod); - } - }); - return; - } - callWindowMethod(windowMethod); - }; - element.removeEventListener(trigger, callback); - element.addEventListener(trigger, callback); - }); - } - function addWMLOpenBrowserListener() { - const elements = document.querySelectorAll("[wml-openurl]"); - elements.forEach(function(element) { - const url = element.getAttribute("wml-openurl"); - const confirm = element.getAttribute("wml-confirm"); - const trigger = element.getAttribute("wml-trigger") || "click"; - let callback = function() { - if (confirm) { - Question({ Title: "Confirm", Message: confirm, Buttons: [{ Label: "Yes" }, { Label: "No", IsDefault: true }] }).then(function(result) { - if (result !== "No") { - void wails.Browser.OpenURL(url); - } - }); - return; - } - void wails.Browser.OpenURL(url); - }; - element.removeEventListener(trigger, callback); - element.addEventListener(trigger, callback); - }); - } - function reloadWML() { - addWMLEventListeners(); - addWMLWindowListeners(); - addWMLOpenBrowserListener(); - } - - // desktop/invoke.js - var invoke = function(input) { - if (false) { - chrome.webview.postMessage(input); - } else { - webkit.messageHandlers.external.postMessage(input); - } - }; - - // desktop/flags.js - var flags = /* @__PURE__ */ new Map(); - function convertToMap(obj) { - const map = /* @__PURE__ */ new Map(); - for (const [key, value] of Object.entries(obj)) { - if (typeof value === "object" && value !== null) { - map.set(key, convertToMap(value)); - } else { - map.set(key, value); - } - } - return map; - } - fetch("/wails/flags").then((response) => { - response.json().then((data) => { - flags = convertToMap(data); - }); - }); - - // desktop/drag.js - var shouldDrag = false; - function dragTest(e) { - let val = window.getComputedStyle(e.target).getPropertyValue("--webkit-app-region"); - if (val) { - val = val.trim(); - } - if (val !== "drag") { - return false; - } - if (e.buttons !== 1) { - return false; - } - return e.detail === 1; - } - function setupDrag() { - window.addEventListener("mousedown", onMouseDown); - window.addEventListener("mousemove", onMouseMove); - window.addEventListener("mouseup", onMouseUp); - } - var resizable = false; - function setResizable(value) { - resizable = value; - } - function onMouseDown(e) { - if (false) { - if (testResize()) { - return; - } - } - if (dragTest(e)) { - if (e.offsetX > e.target.clientWidth || e.offsetY > e.target.clientHeight) { - return; - } - shouldDrag = true; - } else { - shouldDrag = false; - } - } - function onMouseUp(e) { - let mousePressed = e.buttons !== void 0 ? e.buttons : e.which; - if (mousePressed > 0) { - endDrag(); - } - } - function endDrag() { - document.body.style.cursor = "default"; - shouldDrag = false; - } - function onMouseMove(e) { - if (shouldDrag) { - shouldDrag = false; - let mousePressed = e.buttons !== void 0 ? e.buttons : e.which; - if (mousePressed > 0) { - invoke("drag"); - } - return; - } - if (false) { - if (resizable) { - handleResize(e); - } - } - } - - // desktop/main.js - window.wails = { - ...newRuntime(null), - Capabilities: {}, - clientId - }; - fetch("/wails/capabilities").then((response) => { - response.json().then((data) => { - window.wails.Capabilities = data; - }); - }); - window._wails = { - dialogCallback, - dialogErrorCallback, - dispatchWailsEvent, - callCallback, - callErrorCallback, - endDrag, - setResizable - }; - function newRuntime(windowName) { - return { - Clipboard: { - ...clipboard_exports - }, - Application: { - ...application_exports, - GetWindowByName(windowName2) { - return newRuntime(windowName2); - } - }, - System: system_exports, - Screens: screens_exports, - Browser: browser_exports, - Call, - CallByID, - CallByName, - Plugin, - WML: { - Reload: reloadWML - }, - Dialog: { - Info, - Warning, - Error: Error2, - Question, - OpenFile, - SaveFile - }, - Events: { - Emit, - On, - Once, - OnMultiple, - Off, - OffAll - }, - Window: newWindow(windowName) - }; - } - if (true) { - console.log("Wails v3.0.0 Debug Mode Enabled"); - } - setupContextMenus(); - setupDrag(); - document.addEventListener("DOMContentLoaded", function() { - reloadWML(); - }); -})(); -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiZGVza3RvcC9jbGlwYm9hcmQuanMiLCAibm9kZV9tb2R1bGVzL25hbm9pZC9ub24tc2VjdXJlL2luZGV4LmpzIiwgImRlc2t0b3AvcnVudGltZS5qcyIsICJkZXNrdG9wL2FwcGxpY2F0aW9uLmpzIiwgImRlc2t0b3Avc2NyZWVucy5qcyIsICJkZXNrdG9wL3N5c3RlbS5qcyIsICJkZXNrdG9wL2Jyb3dzZXIuanMiLCAiZGVza3RvcC9jYWxscy5qcyIsICJkZXNrdG9wL3dpbmRvdy5qcyIsICJkZXNrdG9wL2V2ZW50cy5qcyIsICJkZXNrdG9wL2RpYWxvZ3MuanMiLCAiZGVza3RvcC9jb250ZXh0bWVudS5qcyIsICJkZXNrdG9wL3dtbC5qcyIsICJkZXNrdG9wL2ludm9rZS5qcyIsICJkZXNrdG9wL2ZsYWdzLmpzIiwgImRlc2t0b3AvZHJhZy5qcyIsICJkZXNrdG9wL21haW4uanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmxldCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5DbGlwYm9hcmQpO1xyXG5cclxubGV0IENsaXBib2FyZFNldFRleHQgPSAwO1xyXG5sZXQgQ2xpcGJvYXJkVGV4dCA9IDE7XHJcblxyXG4vKipcclxuICogU2V0IHRoZSBDbGlwYm9hcmQgdGV4dFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIFNldFRleHQodGV4dCkge1xyXG4gICAgdm9pZCBjYWxsKENsaXBib2FyZFNldFRleHQsIHt0ZXh0fSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgdGhlIENsaXBib2FyZCB0ZXh0XHJcbiAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZz59XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gVGV4dCgpIHtcclxuICAgIHJldHVybiBjYWxsKENsaXBib2FyZFRleHQpO1xyXG59IiwgImxldCB1cmxBbHBoYWJldCA9XG4gICd1c2VhbmRvbS0yNlQxOTgzNDBQWDc1cHhKQUNLVkVSWU1JTkRCVVNIV09MRl9HUVpiZmdoamtscXZ3eXpyaWN0J1xuZXhwb3J0IGxldCBjdXN0b21BbHBoYWJldCA9IChhbHBoYWJldCwgZGVmYXVsdFNpemUgPSAyMSkgPT4ge1xuICByZXR1cm4gKHNpemUgPSBkZWZhdWx0U2l6ZSkgPT4ge1xuICAgIGxldCBpZCA9ICcnXG4gICAgbGV0IGkgPSBzaXplXG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgaWQgKz0gYWxwaGFiZXRbKE1hdGgucmFuZG9tKCkgKiBhbHBoYWJldC5sZW5ndGgpIHwgMF1cbiAgICB9XG4gICAgcmV0dXJuIGlkXG4gIH1cbn1cbmV4cG9ydCBsZXQgbmFub2lkID0gKHNpemUgPSAyMSkgPT4ge1xuICBsZXQgaWQgPSAnJ1xuICBsZXQgaSA9IHNpemVcbiAgd2hpbGUgKGktLSkge1xuICAgIGlkICs9IHVybEFscGhhYmV0WyhNYXRoLnJhbmRvbSgpICogNjQpIHwgMF1cbiAgfVxuICByZXR1cm4gaWRcbn1cbiIsICIvKlxyXG4gXyAgICAgX18gICAgIF8gX19cclxufCB8ICAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcbmltcG9ydCB7IG5hbm9pZCB9IGZyb20gJ25hbm9pZC9ub24tc2VjdXJlJztcclxuXHJcbmNvbnN0IHJ1bnRpbWVVUkwgPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luICsgXCIvd2FpbHMvcnVudGltZVwiO1xyXG4vLyBPYmplY3QgTmFtZXNcclxuZXhwb3J0IGNvbnN0IG9iamVjdE5hbWVzID0ge1xyXG4gICAgQ2FsbDogMCxcclxuICAgIENsaXBib2FyZDogMSxcclxuICAgIEFwcGxpY2F0aW9uOiAyLFxyXG4gICAgRXZlbnRzOiAzLFxyXG4gICAgQ29udGV4dE1lbnU6IDQsXHJcbiAgICBEaWFsb2c6IDUsXHJcbiAgICBXaW5kb3c6IDYsXHJcbiAgICBTY3JlZW5zOiA3LFxyXG4gICAgU3lzdGVtOiA4LFxyXG4gICAgQnJvd3NlcjogOSxcclxufVxyXG5leHBvcnQgbGV0IGNsaWVudElkID0gbmFub2lkKCk7XHJcblxyXG5mdW5jdGlvbiBydW50aW1lQ2FsbChtZXRob2QsIHdpbmRvd05hbWUsIGFyZ3MpIHtcclxuICAgIGxldCB1cmwgPSBuZXcgVVJMKHJ1bnRpbWVVUkwpO1xyXG4gICAgaWYoIG1ldGhvZCApIHtcclxuICAgICAgICB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChcIm1ldGhvZFwiLCBtZXRob2QpO1xyXG4gICAgfVxyXG4gICAgbGV0IGZldGNoT3B0aW9ucyA9IHtcclxuICAgICAgICBoZWFkZXJzOiB7fSxcclxuICAgIH07XHJcbiAgICBpZiAod2luZG93TmFtZSkge1xyXG4gICAgICAgIGZldGNoT3B0aW9ucy5oZWFkZXJzW1wieC13YWlscy13aW5kb3ctbmFtZVwiXSA9IHdpbmRvd05hbWU7XHJcbiAgICB9XHJcbiAgICBpZiAoYXJncykge1xyXG4gICAgICAgIHVybC5zZWFyY2hQYXJhbXMuYXBwZW5kKFwiYXJnc1wiLCBKU09OLnN0cmluZ2lmeShhcmdzKSk7XHJcbiAgICB9XHJcbiAgICBmZXRjaE9wdGlvbnMuaGVhZGVyc1tcIngtd2FpbHMtY2xpZW50LWlkXCJdID0gY2xpZW50SWQ7XHJcblxyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICBmZXRjaCh1cmwsIGZldGNoT3B0aW9ucylcclxuICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgY29udGVudCB0eXBlXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiQ29udGVudC1UeXBlXCIpICYmIHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiQ29udGVudC1UeXBlXCIpLmluZGV4T2YoXCJhcHBsaWNhdGlvbi9qc29uXCIpICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZS50ZXh0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKHJlc3BvbnNlLnN0YXR1c1RleHQpKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLnRoZW4oZGF0YSA9PiByZXNvbHZlKGRhdGEpKVxyXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIG5ld1J1bnRpbWVDYWxsZXIob2JqZWN0LCB3aW5kb3dOYW1lKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKG1ldGhvZCwgYXJncz1udWxsKSB7XHJcbiAgICAgICAgcmV0dXJuIHJ1bnRpbWVDYWxsKG9iamVjdCArIFwiLlwiICsgbWV0aG9kLCB3aW5kb3dOYW1lLCBhcmdzKTtcclxuICAgIH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJ1bnRpbWVDYWxsV2l0aElEKG9iamVjdElELCBtZXRob2QsIHdpbmRvd05hbWUsIGFyZ3MpIHtcclxuICAgIGxldCB1cmwgPSBuZXcgVVJMKHJ1bnRpbWVVUkwpO1xyXG4gICAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoXCJvYmplY3RcIiwgb2JqZWN0SUQpO1xyXG4gICAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoXCJtZXRob2RcIiwgbWV0aG9kKTtcclxuICAgIGxldCBmZXRjaE9wdGlvbnMgPSB7XHJcbiAgICAgICAgaGVhZGVyczoge30sXHJcbiAgICB9O1xyXG4gICAgaWYgKHdpbmRvd05hbWUpIHtcclxuICAgICAgICBmZXRjaE9wdGlvbnMuaGVhZGVyc1tcIngtd2FpbHMtd2luZG93LW5hbWVcIl0gPSB3aW5kb3dOYW1lO1xyXG4gICAgfVxyXG4gICAgaWYgKGFyZ3MpIHtcclxuICAgICAgICB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChcImFyZ3NcIiwgSlNPTi5zdHJpbmdpZnkoYXJncykpO1xyXG4gICAgfVxyXG4gICAgZmV0Y2hPcHRpb25zLmhlYWRlcnNbXCJ4LXdhaWxzLWNsaWVudC1pZFwiXSA9IGNsaWVudElkO1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICBmZXRjaCh1cmwsIGZldGNoT3B0aW9ucylcclxuICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgY29udGVudCB0eXBlXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiQ29udGVudC1UeXBlXCIpICYmIHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiQ29udGVudC1UeXBlXCIpLmluZGV4T2YoXCJhcHBsaWNhdGlvbi9qc29uXCIpICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZS50ZXh0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKHJlc3BvbnNlLnN0YXR1c1RleHQpKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLnRoZW4oZGF0YSA9PiByZXNvbHZlKGRhdGEpKVxyXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIG5ld1J1bnRpbWVDYWxsZXJXaXRoSUQob2JqZWN0LCB3aW5kb3dOYW1lKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKG1ldGhvZCwgYXJncz1udWxsKSB7XHJcbiAgICAgICAgcmV0dXJuIHJ1bnRpbWVDYWxsV2l0aElEKG9iamVjdCwgbWV0aG9kLCB3aW5kb3dOYW1lLCBhcmdzKTtcclxuICAgIH07XHJcbn1cclxuIiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmxldCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5BcHBsaWNhdGlvbik7XHJcblxyXG5sZXQgbWV0aG9kcyA9IHtcclxuICAgIEhpZGU6IDAsXHJcbiAgICBTaG93OiAxLFxyXG4gICAgUXVpdDogMixcclxufVxyXG5cclxuLyoqXHJcbiAqIEhpZGUgdGhlIGFwcGxpY2F0aW9uXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gSGlkZSgpIHtcclxuICAgIHZvaWQgY2FsbChtZXRob2RzLkhpZGUpO1xyXG59XHJcblxyXG4vKipcclxuICogU2hvdyB0aGUgYXBwbGljYXRpb25cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBTaG93KCkge1xyXG4gICAgdm9pZCBjYWxsKG1ldGhvZHMuU2hvdyk7XHJcbn1cclxuXHJcblxyXG4vKipcclxuICogUXVpdCB0aGUgYXBwbGljYXRpb25cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBRdWl0KCkge1xyXG4gICAgdm9pZCBjYWxsKG1ldGhvZHMuUXVpdCk7XHJcbn0iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuLyoganNoaW50IGVzdmVyc2lvbjogOSAqL1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL2FwaS90eXBlc1wiKS5TY3JlZW59IFNjcmVlblxyXG4gKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmxldCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5TY3JlZW5zKTtcclxuXHJcbmxldCBTY3JlZW5zR2V0QWxsID0gMDtcclxubGV0IFNjcmVlbnNHZXRQcmltYXJ5ID0gMTtcclxubGV0IFNjcmVlbnNHZXRDdXJyZW50ID0gMjtcclxuXHJcbi8qKlxyXG4gKiBHZXRzIGFsbCBzY3JlZW5zLlxyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxTY3JlZW5bXT59XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gR2V0QWxsKCkge1xyXG4gICAgcmV0dXJuIGNhbGwoU2NyZWVuc0dldEFsbCk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBwcmltYXJ5IHNjcmVlbi5cclxuICogQHJldHVybnMge1Byb21pc2U8U2NyZWVuPn1cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBHZXRQcmltYXJ5KCkge1xyXG4gICAgcmV0dXJuIGNhbGwoU2NyZWVuc0dldFByaW1hcnkpO1xyXG59XHJcblxyXG4vKipcclxuICogR2V0cyB0aGUgY3VycmVudCBhY3RpdmUgc2NyZWVuLlxyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxTY3JlZW4+fVxyXG4gKiBAY29uc3RydWN0b3JcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBHZXRDdXJyZW50KCkge1xyXG4gICAgcmV0dXJuIGNhbGwoU2NyZWVuc0dldEN1cnJlbnQpO1xyXG59IiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmxldCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5TeXN0ZW0pO1xyXG5cclxubGV0IFN5c3RlbUlzRGFya01vZGUgPSAwO1xyXG5cclxuLyoqXHJcbiAqIERldGVybWluZXMgaWYgdGhlIHN5c3RlbSBpcyBjdXJyZW50bHkgdXNpbmcgZGFyayBtb2RlXHJcbiAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIElzRGFya01vZGUoKSB7XHJcbiAgICByZXR1cm4gY2FsbChTeXN0ZW1Jc0RhcmtNb2RlKTtcclxufSIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcblxyXG5pbXBvcnQge25ld1J1bnRpbWVDYWxsZXJXaXRoSUQsIG9iamVjdE5hbWVzfSBmcm9tIFwiLi9ydW50aW1lXCI7XHJcblxyXG5sZXQgY2FsbCA9IG5ld1J1bnRpbWVDYWxsZXJXaXRoSUQob2JqZWN0TmFtZXMuQnJvd3Nlcik7XHJcblxyXG5sZXQgQnJvd3Nlck9wZW5VUkwgPSAwO1xyXG5cclxuLyoqXHJcbiAqIE9wZW4gYSBicm93c2VyIHdpbmRvdyB0byB0aGUgZ2l2ZW4gVVJMXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgLSBUaGUgVVJMIHRvIG9wZW5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBPcGVuVVJMKHVybCkge1xyXG4gICAgdm9pZCBjYWxsKEJyb3dzZXJPcGVuVVJMLCB7dXJsfSk7XHJcbn1cclxuIiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmltcG9ydCB7IG5hbm9pZCB9IGZyb20gJ25hbm9pZC9ub24tc2VjdXJlJztcclxuXHJcbmxldCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5DYWxsKTtcclxuXHJcbmxldCBDYWxsQmluZGluZyA9IDA7XHJcblxyXG5sZXQgY2FsbFJlc3BvbnNlcyA9IG5ldyBNYXAoKTtcclxuXHJcbmZ1bmN0aW9uIGdlbmVyYXRlSUQoKSB7XHJcbiAgICBsZXQgcmVzdWx0O1xyXG4gICAgZG8ge1xyXG4gICAgICAgIHJlc3VsdCA9IG5hbm9pZCgpO1xyXG4gICAgfSB3aGlsZSAoY2FsbFJlc3BvbnNlcy5oYXMocmVzdWx0KSk7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY2FsbENhbGxiYWNrKGlkLCBkYXRhLCBpc0pTT04pIHtcclxuICAgIGxldCBwID0gY2FsbFJlc3BvbnNlcy5nZXQoaWQpO1xyXG4gICAgaWYgKHApIHtcclxuICAgICAgICBpZiAoaXNKU09OKSB7XHJcbiAgICAgICAgICAgIHAucmVzb2x2ZShKU09OLnBhcnNlKGRhdGEpKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBwLnJlc29sdmUoZGF0YSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhbGxSZXNwb25zZXMuZGVsZXRlKGlkKTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGNhbGxFcnJvckNhbGxiYWNrKGlkLCBtZXNzYWdlKSB7XHJcbiAgICBsZXQgcCA9IGNhbGxSZXNwb25zZXMuZ2V0KGlkKTtcclxuICAgIGlmIChwKSB7XHJcbiAgICAgICAgcC5yZWplY3QobWVzc2FnZSk7XHJcbiAgICAgICAgY2FsbFJlc3BvbnNlcy5kZWxldGUoaWQpO1xyXG4gICAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBjYWxsQmluZGluZyh0eXBlLCBvcHRpb25zKSB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgIGxldCBpZCA9IGdlbmVyYXRlSUQoKTtcclxuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcclxuICAgICAgICBvcHRpb25zW1wiY2FsbC1pZFwiXSA9IGlkO1xyXG5cclxuICAgICAgICBjYWxsUmVzcG9uc2VzLnNldChpZCwge3Jlc29sdmUsIHJlamVjdH0pO1xyXG4gICAgICAgIGNhbGwodHlwZSwgb3B0aW9ucykuY2F0Y2goKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAgIHJlamVjdChlcnJvcik7XHJcbiAgICAgICAgICAgIGNhbGxSZXNwb25zZXMuZGVsZXRlKGlkKTtcclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gQ2FsbChvcHRpb25zKSB7XHJcbiAgICByZXR1cm4gY2FsbEJpbmRpbmcoQ2FsbEJpbmRpbmcsIG9wdGlvbnMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gQ2FsbEJ5TmFtZShuYW1lLCAuLi5hcmdzKSB7XHJcblxyXG4gICAgLy8gRW5zdXJlIGZpcnN0IGFyZ3VtZW50IGlzIGEgc3RyaW5nIGFuZCBoYXMgMiBkb3RzXHJcbiAgICBpZiAodHlwZW9mIG5hbWUgIT09IFwic3RyaW5nXCIgfHwgbmFtZS5zcGxpdChcIi5cIikubGVuZ3RoICE9PSAzKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FsbEJ5TmFtZSByZXF1aXJlcyBhIHN0cmluZyBpbiB0aGUgZm9ybWF0ICdwYWNrYWdlLnN0cnVjdC5tZXRob2QnXCIpO1xyXG4gICAgfVxyXG4gICAgLy8gU3BsaXQgaW5wdXRzXHJcbiAgICBsZXQgcGFydHMgPSBuYW1lLnNwbGl0KFwiLlwiKTtcclxuXHJcbiAgICByZXR1cm4gY2FsbEJpbmRpbmcoQ2FsbEJpbmRpbmcsIHtcclxuICAgICAgICBwYWNrYWdlTmFtZTogcGFydHNbMF0sXHJcbiAgICAgICAgc3RydWN0TmFtZTogcGFydHNbMV0sXHJcbiAgICAgICAgbWV0aG9kTmFtZTogcGFydHNbMl0sXHJcbiAgICAgICAgYXJnczogYXJncyxcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gQ2FsbEJ5SUQobWV0aG9kSUQsIC4uLmFyZ3MpIHtcclxuICAgIHJldHVybiBjYWxsQmluZGluZyhDYWxsQmluZGluZywge1xyXG4gICAgICAgIG1ldGhvZElEOiBtZXRob2RJRCxcclxuICAgICAgICBhcmdzOiBhcmdzLFxyXG4gICAgfSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDYWxsIGEgcGx1Z2luIG1ldGhvZFxyXG4gKiBAcGFyYW0ge3N0cmluZ30gcGx1Z2luTmFtZSAtIG5hbWUgb2YgdGhlIHBsdWdpblxyXG4gKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kTmFtZSAtIG5hbWUgb2YgdGhlIG1ldGhvZFxyXG4gKiBAcGFyYW0gey4uLmFueX0gYXJncyAtIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBtZXRob2RcclxuICogQHJldHVybnMge1Byb21pc2U8YW55Pn0gLSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgcmVzdWx0XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gUGx1Z2luKHBsdWdpbk5hbWUsIG1ldGhvZE5hbWUsIC4uLmFyZ3MpIHtcclxuICAgIHJldHVybiBjYWxsQmluZGluZyhDYWxsQmluZGluZywge1xyXG4gICAgICAgIHBhY2thZ2VOYW1lOiBcIndhaWxzLXBsdWdpbnNcIixcclxuICAgICAgICBzdHJ1Y3ROYW1lOiBwbHVnaW5OYW1lLFxyXG4gICAgICAgIG1ldGhvZE5hbWU6IG1ldGhvZE5hbWUsXHJcbiAgICAgICAgYXJnczogYXJncyxcclxuICAgIH0pO1xyXG59IiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbi8qKlxyXG4gKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi4vYXBpL3R5cGVzXCIpLlNpemV9IFNpemVcclxuICogQHR5cGVkZWYge2ltcG9ydChcIi4uL2FwaS90eXBlc1wiKS5Qb3NpdGlvbn0gUG9zaXRpb25cclxuICogQHR5cGVkZWYge2ltcG9ydChcIi4uL2FwaS90eXBlc1wiKS5TY3JlZW59IFNjcmVlblxyXG4gKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmxldCBXaW5kb3dDZW50ZXIgPSAwO1xyXG5sZXQgV2luZG93U2V0VGl0bGUgPSAxO1xyXG5sZXQgV2luZG93RnVsbHNjcmVlbiA9IDI7XHJcbmxldCBXaW5kb3dVbkZ1bGxzY3JlZW4gPSAzO1xyXG5sZXQgV2luZG93U2V0U2l6ZSA9IDQ7XHJcbmxldCBXaW5kb3dTaXplID0gNTtcclxubGV0IFdpbmRvd1NldE1heFNpemUgPSA2O1xyXG5sZXQgV2luZG93U2V0TWluU2l6ZSA9IDc7XHJcbmxldCBXaW5kb3dTZXRBbHdheXNPblRvcCA9IDg7XHJcbmxldCBXaW5kb3dTZXRSZWxhdGl2ZVBvc2l0aW9uID0gOTtcclxubGV0IFdpbmRvd1JlbGF0aXZlUG9zaXRpb24gPSAxMDtcclxubGV0IFdpbmRvd1NjcmVlbiA9IDExO1xyXG5sZXQgV2luZG93SGlkZSA9IDEyO1xyXG5sZXQgV2luZG93TWF4aW1pc2UgPSAxMztcclxubGV0IFdpbmRvd1VuTWF4aW1pc2UgPSAxNDtcclxubGV0IFdpbmRvd1RvZ2dsZU1heGltaXNlID0gMTU7XHJcbmxldCBXaW5kb3dNaW5pbWlzZSA9IDE2O1xyXG5sZXQgV2luZG93VW5NaW5pbWlzZSA9IDE3O1xyXG5sZXQgV2luZG93UmVzdG9yZSA9IDE4O1xyXG5sZXQgV2luZG93U2hvdyA9IDE5O1xyXG5sZXQgV2luZG93Q2xvc2UgPSAyMDtcclxubGV0IFdpbmRvd1NldEJhY2tncm91bmRDb2xvdXIgPSAyMTtcclxubGV0IFdpbmRvd1NldFJlc2l6YWJsZSA9IDIyO1xyXG5sZXQgV2luZG93V2lkdGggPSAyMztcclxubGV0IFdpbmRvd0hlaWdodCA9IDI0O1xyXG5sZXQgV2luZG93Wm9vbUluID0gMjU7XHJcbmxldCBXaW5kb3dab29tT3V0ID0gMjY7XHJcbmxldCBXaW5kb3dab29tUmVzZXQgPSAyNztcclxubGV0IFdpbmRvd0dldFpvb21MZXZlbCA9IDI4O1xyXG5sZXQgV2luZG93U2V0Wm9vbUxldmVsID0gMjk7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbmV3V2luZG93KHdpbmRvd05hbWUpIHtcclxuICAgIGxldCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5XaW5kb3csIHdpbmRvd05hbWUpO1xyXG4gICAgcmV0dXJuIHtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ2VudGVycyB0aGUgd2luZG93LlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIENlbnRlcjogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd0NlbnRlciksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFNldCB0aGUgd2luZG93IHRpdGxlLlxyXG4gICAgICAgICAqIEBwYXJhbSB0aXRsZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFNldFRpdGxlOiAodGl0bGUpID0+IHZvaWQgY2FsbChXaW5kb3dTZXRUaXRsZSwge3RpdGxlfSksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIE1ha2VzIHRoZSB3aW5kb3cgZnVsbHNjcmVlbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICBGdWxsc2NyZWVuOiAoKSA9PiB2b2lkIGNhbGwoV2luZG93RnVsbHNjcmVlbiksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFVuZnVsbHNjcmVlbiB0aGUgd2luZG93LlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFVuRnVsbHNjcmVlbjogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd1VuRnVsbHNjcmVlbiksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFNldCB0aGUgd2luZG93IHNpemUuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoIFRoZSB3aW5kb3cgd2lkdGhcclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IFRoZSB3aW5kb3cgaGVpZ2h0XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgU2V0U2l6ZTogKHdpZHRoLCBoZWlnaHQpID0+IGNhbGwoV2luZG93U2V0U2l6ZSwge3dpZHRoLGhlaWdodH0pLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXQgdGhlIHdpbmRvdyBzaXplLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtQcm9taXNlPFNpemU+fSBUaGUgd2luZG93IHNpemVcclxuICAgICAgICAgKi9cclxuICAgICAgICBTaXplOiAoKSA9PiB7IHJldHVybiBjYWxsKFdpbmRvd1NpemUpOyB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgdGhlIHdpbmRvdyBtYXhpbXVtIHNpemUuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFNldE1heFNpemU6ICh3aWR0aCwgaGVpZ2h0KSA9PiB2b2lkIGNhbGwoV2luZG93U2V0TWF4U2l6ZSwge3dpZHRoLGhlaWdodH0pLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgdGhlIHdpbmRvdyBtaW5pbXVtIHNpemUuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFNldE1pblNpemU6ICh3aWR0aCwgaGVpZ2h0KSA9PiB2b2lkIGNhbGwoV2luZG93U2V0TWluU2l6ZSwge3dpZHRoLGhlaWdodH0pLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgd2luZG93IHRvIGJlIGFsd2F5cyBvbiB0b3AuXHJcbiAgICAgICAgICogQHBhcmFtIHtib29sZWFufSBvblRvcCBXaGV0aGVyIHRoZSB3aW5kb3cgc2hvdWxkIGJlIGFsd2F5cyBvbiB0b3BcclxuICAgICAgICAgKi9cclxuICAgICAgICBTZXRBbHdheXNPblRvcDogKG9uVG9wKSA9PiB2b2lkIGNhbGwoV2luZG93U2V0QWx3YXlzT25Ub3AsIHthbHdheXNPblRvcDpvblRvcH0pLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgdGhlIHdpbmRvdyByZWxhdGl2ZSBwb3NpdGlvbi5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0geFxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgU2V0UmVsYXRpdmVQb3NpdGlvbjogKHgsIHkpID0+IGNhbGwoV2luZG93U2V0UmVsYXRpdmVQb3NpdGlvbiwge3gseX0pLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXQgdGhlIHdpbmRvdyBwb3NpdGlvbi5cclxuICAgICAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxQb3NpdGlvbj59IFRoZSB3aW5kb3cgcG9zaXRpb25cclxuICAgICAgICAgKi9cclxuICAgICAgICBSZWxhdGl2ZVBvc2l0aW9uOiAoKSA9PiB7IHJldHVybiBjYWxsKFdpbmRvd1JlbGF0aXZlUG9zaXRpb24pOyB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXQgdGhlIHNjcmVlbiB0aGUgd2luZG93IGlzIG9uLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtQcm9taXNlPFNjcmVlbj59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgU2NyZWVuOiAoKSA9PiB7IHJldHVybiBjYWxsKFdpbmRvd1NjcmVlbik7IH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEhpZGUgdGhlIHdpbmRvd1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEhpZGU6ICgpID0+IHZvaWQgY2FsbChXaW5kb3dIaWRlKSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogTWF4aW1pc2UgdGhlIHdpbmRvd1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIE1heGltaXNlOiAoKSA9PiB2b2lkIGNhbGwoV2luZG93TWF4aW1pc2UpLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTaG93IHRoZSB3aW5kb3dcclxuICAgICAgICAgKi9cclxuICAgICAgICBTaG93OiAoKSA9PiB2b2lkIGNhbGwoV2luZG93U2hvdyksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENsb3NlIHRoZSB3aW5kb3dcclxuICAgICAgICAgKi9cclxuICAgICAgICBDbG9zZTogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd0Nsb3NlKSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVG9nZ2xlIHRoZSB3aW5kb3cgbWF4aW1pc2Ugc3RhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBUb2dnbGVNYXhpbWlzZTogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd1RvZ2dsZU1heGltaXNlKSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVW5tYXhpbWlzZSB0aGUgd2luZG93XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgVW5NYXhpbWlzZTogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd1VuTWF4aW1pc2UpLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBNaW5pbWlzZSB0aGUgd2luZG93XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgTWluaW1pc2U6ICgpID0+IHZvaWQgY2FsbChXaW5kb3dNaW5pbWlzZSksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFVubWluaW1pc2UgdGhlIHdpbmRvd1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFVuTWluaW1pc2U6ICgpID0+IHZvaWQgY2FsbChXaW5kb3dVbk1pbmltaXNlKSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmVzdG9yZSB0aGUgd2luZG93XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgUmVzdG9yZTogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd1Jlc3RvcmUpLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgdGhlIGJhY2tncm91bmQgY29sb3VyIG9mIHRoZSB3aW5kb3cuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHIgLSBBIHZhbHVlIGJldHdlZW4gMCBhbmQgMjU1XHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGcgLSBBIHZhbHVlIGJldHdlZW4gMCBhbmQgMjU1XHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGIgLSBBIHZhbHVlIGJldHdlZW4gMCBhbmQgMjU1XHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGEgLSBBIHZhbHVlIGJldHdlZW4gMCBhbmQgMjU1XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgU2V0QmFja2dyb3VuZENvbG91cjogKHIsIGcsIGIsIGEpID0+IHZvaWQgY2FsbChXaW5kb3dTZXRCYWNrZ3JvdW5kQ29sb3VyLCB7ciwgZywgYiwgYX0pLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgd2hldGhlciB0aGUgd2luZG93IGNhbiBiZSByZXNpemVkIG9yIG5vdFxyXG4gICAgICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gcmVzaXphYmxlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgU2V0UmVzaXphYmxlOiAocmVzaXphYmxlKSA9PiB2b2lkIGNhbGwoV2luZG93U2V0UmVzaXphYmxlLCB7cmVzaXphYmxlfSksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEdldCB0aGUgd2luZG93IHdpZHRoXHJcbiAgICAgICAgICogQHJldHVybnMge1Byb21pc2U8bnVtYmVyPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBXaWR0aDogKCkgPT4geyByZXR1cm4gY2FsbChXaW5kb3dXaWR0aCk7IH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEdldCB0aGUgd2luZG93IGhlaWdodFxyXG4gICAgICAgICAqIEByZXR1cm5zIHtQcm9taXNlPG51bWJlcj59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgSGVpZ2h0OiAoKSA9PiB7IHJldHVybiBjYWxsKFdpbmRvd0hlaWdodCk7IH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFpvb20gaW4gdGhlIHdpbmRvd1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFpvb21JbjogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd1pvb21JbiksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFpvb20gb3V0IHRoZSB3aW5kb3dcclxuICAgICAgICAgKi9cclxuICAgICAgICBab29tT3V0OiAoKSA9PiB2b2lkIGNhbGwoV2luZG93Wm9vbU91dCksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJlc2V0IHRoZSB3aW5kb3cgem9vbVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFpvb21SZXNldDogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd1pvb21SZXNldCksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEdldCB0aGUgd2luZG93IHpvb21cclxuICAgICAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxudW1iZXI+fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEdldFpvb21MZXZlbDogKCkgPT4geyByZXR1cm4gY2FsbChXaW5kb3dHZXRab29tTGV2ZWwpOyB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgdGhlIHdpbmRvdyB6b29tIGxldmVsXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHpvb21MZXZlbFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFNldFpvb21MZXZlbDogKHpvb21MZXZlbCkgPT4gdm9pZCBjYWxsKFdpbmRvd1NldFpvb21MZXZlbCwge3pvb21MZXZlbH0pLFxyXG4gICAgfTtcclxufVxyXG4iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuLyoganNoaW50IGVzdmVyc2lvbjogOSAqL1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL2FwaS90eXBlc1wiKS5XYWlsc0V2ZW50fSBXYWlsc0V2ZW50XHJcbiAqL1xyXG5cclxuaW1wb3J0IHtuZXdSdW50aW1lQ2FsbGVyV2l0aElELCBvYmplY3ROYW1lc30gZnJvbSBcIi4vcnVudGltZVwiO1xyXG5cclxubGV0IGNhbGwgPSBuZXdSdW50aW1lQ2FsbGVyV2l0aElEKG9iamVjdE5hbWVzLkV2ZW50cyk7XHJcbmxldCBFdmVudEVtaXQgPSAwO1xyXG5cclxuLyoqXHJcbiAqIFRoZSBMaXN0ZW5lciBjbGFzcyBkZWZpbmVzIGEgbGlzdGVuZXIhIDotKVxyXG4gKlxyXG4gKiBAY2xhc3MgTGlzdGVuZXJcclxuICovXHJcbmNsYXNzIExpc3RlbmVyIHtcclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBMaXN0ZW5lci5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWVcclxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWF4Q2FsbGJhY2tzXHJcbiAgICAgKiBAbWVtYmVyb2YgTGlzdGVuZXJcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IoZXZlbnROYW1lLCBjYWxsYmFjaywgbWF4Q2FsbGJhY2tzKSB7XHJcbiAgICAgICAgdGhpcy5ldmVudE5hbWUgPSBldmVudE5hbWU7XHJcbiAgICAgICAgLy8gRGVmYXVsdCBvZiAtMSBtZWFucyBpbmZpbml0ZVxyXG4gICAgICAgIHRoaXMubWF4Q2FsbGJhY2tzID0gbWF4Q2FsbGJhY2tzIHx8IC0xO1xyXG4gICAgICAgIC8vIENhbGxiYWNrIGludm9rZXMgdGhlIGNhbGxiYWNrIHdpdGggdGhlIGdpdmVuIGRhdGFcclxuICAgICAgICAvLyBSZXR1cm5zIHRydWUgaWYgdGhpcyBsaXN0ZW5lciBzaG91bGQgYmUgZGVzdHJveWVkXHJcbiAgICAgICAgdGhpcy5DYWxsYmFjayA9IChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgIGNhbGxiYWNrKGRhdGEpO1xyXG4gICAgICAgICAgICAvLyBJZiBtYXhDYWxsYmFja3MgaXMgaW5maW5pdGUsIHJldHVybiBmYWxzZSAoZG8gbm90IGRlc3Ryb3kpXHJcbiAgICAgICAgICAgIGlmICh0aGlzLm1heENhbGxiYWNrcyA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBEZWNyZW1lbnQgbWF4Q2FsbGJhY2tzLiBSZXR1cm4gdHJ1ZSBpZiBub3cgMCwgb3RoZXJ3aXNlIGZhbHNlXHJcbiAgICAgICAgICAgIHRoaXMubWF4Q2FsbGJhY2tzIC09IDE7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1heENhbGxiYWNrcyA9PT0gMDtcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIFdhaWxzRXZlbnQgZGVmaW5lcyBhIGN1c3RvbSBldmVudC4gSXQgaXMgcGFzc2VkIHRvIGV2ZW50IGxpc3RlbmVycy5cclxuICpcclxuICogQGNsYXNzIFdhaWxzRXZlbnRcclxuICogQHByb3BlcnR5IHtzdHJpbmd9IG5hbWUgLSBOYW1lIG9mIHRoZSBldmVudFxyXG4gKiBAcHJvcGVydHkge2FueX0gZGF0YSAtIERhdGEgYXNzb2NpYXRlZCB3aXRoIHRoZSBldmVudFxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIFdhaWxzRXZlbnQge1xyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIFdhaWxzRXZlbnQuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIE5hbWUgb2YgdGhlIGV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge2FueT1udWxsfSBkYXRhIC0gRGF0YSBhc3NvY2lhdGVkIHdpdGggdGhlIGV2ZW50XHJcbiAgICAgKiBAbWVtYmVyb2YgV2FpbHNFdmVudFxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcihuYW1lLCBkYXRhID0gbnVsbCkge1xyXG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XHJcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IGV2ZW50TGlzdGVuZXJzID0gbmV3IE1hcCgpO1xyXG5cclxuLyoqXHJcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBgbWF4Q2FsbGJhY2tzYCB0aW1lcyBiZWZvcmUgYmVpbmcgZGVzdHJveWVkXHJcbiAqXHJcbiAqIEBleHBvcnRcclxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxyXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFdhaWxzRXZlbnQpOiB2b2lkfSBjYWxsYmFja1xyXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4Q2FsbGJhY2tzXHJcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gQSBmdW5jdGlvbiB0byBjYW5jZWwgdGhlIGxpc3RlbmVyXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gT25NdWx0aXBsZShldmVudE5hbWUsIGNhbGxiYWNrLCBtYXhDYWxsYmFja3MpIHtcclxuICAgIGxldCBsaXN0ZW5lcnMgPSBldmVudExpc3RlbmVycy5nZXQoZXZlbnROYW1lKSB8fCBbXTtcclxuICAgIGNvbnN0IHRoaXNMaXN0ZW5lciA9IG5ldyBMaXN0ZW5lcihldmVudE5hbWUsIGNhbGxiYWNrLCBtYXhDYWxsYmFja3MpO1xyXG4gICAgbGlzdGVuZXJzLnB1c2godGhpc0xpc3RlbmVyKTtcclxuICAgIGV2ZW50TGlzdGVuZXJzLnNldChldmVudE5hbWUsIGxpc3RlbmVycyk7XHJcbiAgICByZXR1cm4gKCkgPT4gbGlzdGVuZXJPZmYodGhpc0xpc3RlbmVyKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBldmVyeSB0aW1lIHRoZSBldmVudCBpcyBlbWl0dGVkXHJcbiAqXHJcbiAqIEBleHBvcnRcclxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxyXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFdhaWxzRXZlbnQpOiB2b2lkfSBjYWxsYmFja1xyXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IEEgZnVuY3Rpb24gdG8gY2FuY2VsIHRoZSBsaXN0ZW5lclxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIE9uKGV2ZW50TmFtZSwgY2FsbGJhY2spIHtcclxuICAgIHJldHVybiBPbk11bHRpcGxlKGV2ZW50TmFtZSwgY2FsbGJhY2ssIC0xKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBvbmNlIHRoZW4gZGVzdHJveWVkXHJcbiAqXHJcbiAqIEBleHBvcnRcclxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxyXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFdhaWxzRXZlbnQpOiB2b2lkfSBjYWxsYmFja1xyXG4gQHJldHVybnMge2Z1bmN0aW9ufSBBIGZ1bmN0aW9uIHRvIGNhbmNlbCB0aGUgbGlzdGVuZXJcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBPbmNlKGV2ZW50TmFtZSwgY2FsbGJhY2spIHtcclxuICAgIHJldHVybiBPbk11bHRpcGxlKGV2ZW50TmFtZSwgY2FsbGJhY2ssIDEpO1xyXG59XHJcblxyXG4vKipcclxuICogbGlzdGVuZXJPZmYgdW5yZWdpc3RlcnMgYSBsaXN0ZW5lciBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgd2l0aCBPblxyXG4gKlxyXG4gKiBAcGFyYW0ge0xpc3RlbmVyfSBsaXN0ZW5lclxyXG4gKi9cclxuZnVuY3Rpb24gbGlzdGVuZXJPZmYobGlzdGVuZXIpIHtcclxuICAgIGNvbnN0IGV2ZW50TmFtZSA9IGxpc3RlbmVyLmV2ZW50TmFtZTtcclxuICAgIC8vIFJlbW92ZSBsb2NhbCBsaXN0ZW5lclxyXG4gICAgbGV0IGxpc3RlbmVycyA9IGV2ZW50TGlzdGVuZXJzLmdldChldmVudE5hbWUpLmZpbHRlcihsID0+IGwgIT09IGxpc3RlbmVyKTtcclxuICAgIGlmIChsaXN0ZW5lcnMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgZXZlbnRMaXN0ZW5lcnMuZGVsZXRlKGV2ZW50TmFtZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIGV2ZW50TGlzdGVuZXJzLnNldChldmVudE5hbWUsIGxpc3RlbmVycyk7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBkaXNwYXRjaGVzIGFuIGV2ZW50IHRvIGFsbCBsaXN0ZW5lcnNcclxuICpcclxuICogQGV4cG9ydFxyXG4gKiBAcGFyYW0ge1dhaWxzRXZlbnR9IGV2ZW50XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZGlzcGF0Y2hXYWlsc0V2ZW50KGV2ZW50KSB7XHJcbiAgICBsZXQgbGlzdGVuZXJzID0gZXZlbnRMaXN0ZW5lcnMuZ2V0KGV2ZW50Lm5hbWUpO1xyXG4gICAgaWYgKGxpc3RlbmVycykge1xyXG4gICAgICAgIC8vIGl0ZXJhdGUgbGlzdGVuZXJzIGFuZCBjYWxsIGNhbGxiYWNrLiBJZiBjYWxsYmFjayByZXR1cm5zIHRydWUsIHJlbW92ZSBsaXN0ZW5lclxyXG4gICAgICAgIGxldCB0b1JlbW92ZSA9IFtdO1xyXG4gICAgICAgIGxpc3RlbmVycy5mb3JFYWNoKGxpc3RlbmVyID0+IHtcclxuICAgICAgICAgICAgbGV0IHJlbW92ZSA9IGxpc3RlbmVyLkNhbGxiYWNrKGV2ZW50KTtcclxuICAgICAgICAgICAgaWYgKHJlbW92ZSkge1xyXG4gICAgICAgICAgICAgICAgdG9SZW1vdmUucHVzaChsaXN0ZW5lcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyByZW1vdmUgbGlzdGVuZXJzXHJcbiAgICAgICAgaWYgKHRvUmVtb3ZlLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgbGlzdGVuZXJzID0gbGlzdGVuZXJzLmZpbHRlcihsID0+ICF0b1JlbW92ZS5pbmNsdWRlcyhsKSk7XHJcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBldmVudExpc3RlbmVycy5kZWxldGUoZXZlbnQubmFtZSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBldmVudExpc3RlbmVycy5zZXQoZXZlbnQubmFtZSwgbGlzdGVuZXJzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIE9mZiB1bnJlZ2lzdGVycyBhIGxpc3RlbmVyIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCB3aXRoIE9uLFxyXG4gKiBvcHRpb25hbGx5IG11bHRpcGxlIGxpc3RlbmVycyBjYW4gYmUgdW5yZWdpc3RlcmVkIHZpYSBgYWRkaXRpb25hbEV2ZW50TmFtZXNgXHJcbiAqXHJcbiBbdjMgQ0hBTkdFXSBPZmYgb25seSB1bnJlZ2lzdGVycyBsaXN0ZW5lcnMgd2l0aGluIHRoZSBjdXJyZW50IHdpbmRvd1xyXG4gKlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lXHJcbiAqIEBwYXJhbSAgey4uLnN0cmluZ30gYWRkaXRpb25hbEV2ZW50TmFtZXNcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBPZmYoZXZlbnROYW1lLCAuLi5hZGRpdGlvbmFsRXZlbnROYW1lcykge1xyXG4gICAgbGV0IGV2ZW50c1RvUmVtb3ZlID0gW2V2ZW50TmFtZSwgLi4uYWRkaXRpb25hbEV2ZW50TmFtZXNdO1xyXG4gICAgZXZlbnRzVG9SZW1vdmUuZm9yRWFjaChldmVudE5hbWUgPT4ge1xyXG4gICAgICAgIGV2ZW50TGlzdGVuZXJzLmRlbGV0ZShldmVudE5hbWUpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBPZmZBbGwgdW5yZWdpc3RlcnMgYWxsIGxpc3RlbmVyc1xyXG4gKiBbdjMgQ0hBTkdFXSBPZmZBbGwgb25seSB1bnJlZ2lzdGVycyBsaXN0ZW5lcnMgd2l0aGluIHRoZSBjdXJyZW50IHdpbmRvd1xyXG4gKlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIE9mZkFsbCgpIHtcclxuICAgIGV2ZW50TGlzdGVuZXJzLmNsZWFyKCk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBFbWl0IGFuIGV2ZW50XHJcbiAqIEBwYXJhbSB7V2FpbHNFdmVudH0gZXZlbnQgVGhlIGV2ZW50IHRvIGVtaXRcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBFbWl0KGV2ZW50KSB7XHJcbiAgICB2b2lkIGNhbGwoRXZlbnRFbWl0LCBldmVudCk7XHJcbn0iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuLyoganNoaW50IGVzdmVyc2lvbjogOSAqL1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL2FwaS90eXBlc1wiKS5NZXNzYWdlRGlhbG9nT3B0aW9uc30gTWVzc2FnZURpYWxvZ09wdGlvbnNcclxuICogQHR5cGVkZWYge2ltcG9ydChcIi4vYXBpL3R5cGVzXCIpLk9wZW5EaWFsb2dPcHRpb25zfSBPcGVuRGlhbG9nT3B0aW9uc1xyXG4gKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi9hcGkvdHlwZXNcIikuU2F2ZURpYWxvZ09wdGlvbnN9IFNhdmVEaWFsb2dPcHRpb25zXHJcbiAqL1xyXG5cclxuaW1wb3J0IHtuZXdSdW50aW1lQ2FsbGVyV2l0aElELCBvYmplY3ROYW1lc30gZnJvbSBcIi4vcnVudGltZVwiO1xyXG5cclxuaW1wb3J0IHsgbmFub2lkIH0gZnJvbSAnbmFub2lkL25vbi1zZWN1cmUnO1xyXG5cclxubGV0IGNhbGwgPSBuZXdSdW50aW1lQ2FsbGVyV2l0aElEKG9iamVjdE5hbWVzLkRpYWxvZyk7XHJcblxyXG5sZXQgRGlhbG9nSW5mbyA9IDA7XHJcbmxldCBEaWFsb2dXYXJuaW5nID0gMTtcclxubGV0IERpYWxvZ0Vycm9yID0gMjtcclxubGV0IERpYWxvZ1F1ZXN0aW9uID0gMztcclxubGV0IERpYWxvZ09wZW5GaWxlID0gNDtcclxubGV0IERpYWxvZ1NhdmVGaWxlID0gNTtcclxuXHJcblxyXG5sZXQgZGlhbG9nUmVzcG9uc2VzID0gbmV3IE1hcCgpO1xyXG5cclxuZnVuY3Rpb24gZ2VuZXJhdGVJRCgpIHtcclxuICAgIGxldCByZXN1bHQ7XHJcbiAgICBkbyB7XHJcbiAgICAgICAgcmVzdWx0ID0gbmFub2lkKCk7XHJcbiAgICB9IHdoaWxlIChkaWFsb2dSZXNwb25zZXMuaGFzKHJlc3VsdCkpO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGRpYWxvZ0NhbGxiYWNrKGlkLCBkYXRhLCBpc0pTT04pIHtcclxuICAgIGxldCBwID0gZGlhbG9nUmVzcG9uc2VzLmdldChpZCk7XHJcbiAgICBpZiAocCkge1xyXG4gICAgICAgIGlmIChpc0pTT04pIHtcclxuICAgICAgICAgICAgcC5yZXNvbHZlKEpTT04ucGFyc2UoZGF0YSkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHAucmVzb2x2ZShkYXRhKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZGlhbG9nUmVzcG9uc2VzLmRlbGV0ZShpZCk7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0IGZ1bmN0aW9uIGRpYWxvZ0Vycm9yQ2FsbGJhY2soaWQsIG1lc3NhZ2UpIHtcclxuICAgIGxldCBwID0gZGlhbG9nUmVzcG9uc2VzLmdldChpZCk7XHJcbiAgICBpZiAocCkge1xyXG4gICAgICAgIHAucmVqZWN0KG1lc3NhZ2UpO1xyXG4gICAgICAgIGRpYWxvZ1Jlc3BvbnNlcy5kZWxldGUoaWQpO1xyXG4gICAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBkaWFsb2codHlwZSwgb3B0aW9ucykge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICBsZXQgaWQgPSBnZW5lcmF0ZUlEKCk7XHJcbiAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcbiAgICAgICAgb3B0aW9uc1tcImRpYWxvZy1pZFwiXSA9IGlkO1xyXG4gICAgICAgIGRpYWxvZ1Jlc3BvbnNlcy5zZXQoaWQsIHtyZXNvbHZlLCByZWplY3R9KTtcclxuICAgICAgICBjYWxsKHR5cGUsIG9wdGlvbnMpLmNhdGNoKChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgICByZWplY3QoZXJyb3IpO1xyXG4gICAgICAgICAgICBkaWFsb2dSZXNwb25zZXMuZGVsZXRlKGlkKTtcclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIFNob3dzIGFuIEluZm8gZGlhbG9nIHdpdGggdGhlIGdpdmVuIG9wdGlvbnMuXHJcbiAqIEBwYXJhbSB7TWVzc2FnZURpYWxvZ09wdGlvbnN9IG9wdGlvbnNcclxuICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nPn0gVGhlIGxhYmVsIG9mIHRoZSBidXR0b24gcHJlc3NlZFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIEluZm8ob3B0aW9ucykge1xyXG4gICAgcmV0dXJuIGRpYWxvZyhEaWFsb2dJbmZvLCBvcHRpb25zKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFNob3dzIGEgV2FybmluZyBkaWFsb2cgd2l0aCB0aGUgZ2l2ZW4gb3B0aW9ucy5cclxuICogQHBhcmFtIHtNZXNzYWdlRGlhbG9nT3B0aW9uc30gb3B0aW9uc1xyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fSBUaGUgbGFiZWwgb2YgdGhlIGJ1dHRvbiBwcmVzc2VkXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gV2FybmluZyhvcHRpb25zKSB7XHJcbiAgICByZXR1cm4gZGlhbG9nKERpYWxvZ1dhcm5pbmcsIG9wdGlvbnMpO1xyXG59XHJcblxyXG4vKipcclxuICogU2hvd3MgYW4gRXJyb3IgZGlhbG9nIHdpdGggdGhlIGdpdmVuIG9wdGlvbnMuXHJcbiAqIEBwYXJhbSB7TWVzc2FnZURpYWxvZ09wdGlvbnN9IG9wdGlvbnNcclxuICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nPn0gVGhlIGxhYmVsIG9mIHRoZSBidXR0b24gcHJlc3NlZFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIEVycm9yKG9wdGlvbnMpIHtcclxuICAgIHJldHVybiBkaWFsb2coRGlhbG9nRXJyb3IsIG9wdGlvbnMpO1xyXG59XHJcblxyXG4vKipcclxuICogU2hvd3MgYSBRdWVzdGlvbiBkaWFsb2cgd2l0aCB0aGUgZ2l2ZW4gb3B0aW9ucy5cclxuICogQHBhcmFtIHtNZXNzYWdlRGlhbG9nT3B0aW9uc30gb3B0aW9uc1xyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fSBUaGUgbGFiZWwgb2YgdGhlIGJ1dHRvbiBwcmVzc2VkXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gUXVlc3Rpb24ob3B0aW9ucykge1xyXG4gICAgcmV0dXJuIGRpYWxvZyhEaWFsb2dRdWVzdGlvbiwgb3B0aW9ucyk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBTaG93cyBhbiBPcGVuIGRpYWxvZyB3aXRoIHRoZSBnaXZlbiBvcHRpb25zLlxyXG4gKiBAcGFyYW0ge09wZW5EaWFsb2dPcHRpb25zfSBvcHRpb25zXHJcbiAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZ1tdfHN0cmluZz59IFJldHVybnMgdGhlIHNlbGVjdGVkIGZpbGUgb3IgYW4gYXJyYXkgb2Ygc2VsZWN0ZWQgZmlsZXMgaWYgQWxsb3dzTXVsdGlwbGVTZWxlY3Rpb24gaXMgdHJ1ZS4gQSBibGFuayBzdHJpbmcgaXMgcmV0dXJuZWQgaWYgbm8gZmlsZSB3YXMgc2VsZWN0ZWQuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gT3BlbkZpbGUob3B0aW9ucykge1xyXG4gICAgcmV0dXJuIGRpYWxvZyhEaWFsb2dPcGVuRmlsZSwgb3B0aW9ucyk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBTaG93cyBhIFNhdmUgZGlhbG9nIHdpdGggdGhlIGdpdmVuIG9wdGlvbnMuXHJcbiAqIEBwYXJhbSB7U2F2ZURpYWxvZ09wdGlvbnN9IG9wdGlvbnNcclxuICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nPn0gUmV0dXJucyB0aGUgc2VsZWN0ZWQgZmlsZS4gQSBibGFuayBzdHJpbmcgaXMgcmV0dXJuZWQgaWYgbm8gZmlsZSB3YXMgc2VsZWN0ZWQuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gU2F2ZUZpbGUob3B0aW9ucykge1xyXG4gICAgcmV0dXJuIGRpYWxvZyhEaWFsb2dTYXZlRmlsZSwgb3B0aW9ucyk7XHJcbn1cclxuXHJcbiIsICJpbXBvcnQge25ld1J1bnRpbWVDYWxsZXJXaXRoSUQsIG9iamVjdE5hbWVzfSBmcm9tIFwiLi9ydW50aW1lXCI7XHJcblxyXG5sZXQgY2FsbCA9IG5ld1J1bnRpbWVDYWxsZXJXaXRoSUQob2JqZWN0TmFtZXMuQ29udGV4dE1lbnUpO1xyXG5cclxubGV0IENvbnRleHRNZW51T3BlbiA9IDA7XHJcblxyXG5mdW5jdGlvbiBvcGVuQ29udGV4dE1lbnUoaWQsIHgsIHksIGRhdGEpIHtcclxuICAgIHZvaWQgY2FsbChDb250ZXh0TWVudU9wZW4sIHtpZCwgeCwgeSwgZGF0YX0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gc2V0dXBDb250ZXh0TWVudXMoKSB7XHJcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignY29udGV4dG1lbnUnLCBjb250ZXh0TWVudUhhbmRsZXIpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjb250ZXh0TWVudUhhbmRsZXIoZXZlbnQpIHtcclxuICAgIC8vIENoZWNrIGZvciBjdXN0b20gY29udGV4dCBtZW51XHJcbiAgICBsZXQgZWxlbWVudCA9IGV2ZW50LnRhcmdldDtcclxuICAgIGxldCBjdXN0b21Db250ZXh0TWVudSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpLmdldFByb3BlcnR5VmFsdWUoXCItLWN1c3RvbS1jb250ZXh0bWVudVwiKTtcclxuICAgIGN1c3RvbUNvbnRleHRNZW51ID0gY3VzdG9tQ29udGV4dE1lbnUgPyBjdXN0b21Db250ZXh0TWVudS50cmltKCkgOiBcIlwiO1xyXG4gICAgaWYgKGN1c3RvbUNvbnRleHRNZW51KSB7XHJcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICBsZXQgY3VzdG9tQ29udGV4dE1lbnVEYXRhID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWxlbWVudCkuZ2V0UHJvcGVydHlWYWx1ZShcIi0tY3VzdG9tLWNvbnRleHRtZW51LWRhdGFcIik7XHJcbiAgICAgICAgb3BlbkNvbnRleHRNZW51KGN1c3RvbUNvbnRleHRNZW51LCBldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCBjdXN0b21Db250ZXh0TWVudURhdGEpO1xyXG4gICAgICAgIHJldHVyblxyXG4gICAgfVxyXG5cclxuICAgIHByb2Nlc3NEZWZhdWx0Q29udGV4dE1lbnUoZXZlbnQpO1xyXG59XHJcblxyXG5cclxuLypcclxuLS1kZWZhdWx0LWNvbnRleHRtZW51OiBhdXRvOyAoZGVmYXVsdCkgd2lsbCBzaG93IHRoZSBkZWZhdWx0IGNvbnRleHQgbWVudSBpZiBjb250ZW50RWRpdGFibGUgaXMgdHJ1ZSBPUiB0ZXh0IGhhcyBiZWVuIHNlbGVjdGVkIE9SIGVsZW1lbnQgaXMgaW5wdXQgb3IgdGV4dGFyZWFcclxuLS1kZWZhdWx0LWNvbnRleHRtZW51OiBzaG93OyB3aWxsIGFsd2F5cyBzaG93IHRoZSBkZWZhdWx0IGNvbnRleHQgbWVudVxyXG4tLWRlZmF1bHQtY29udGV4dG1lbnU6IGhpZGU7IHdpbGwgYWx3YXlzIGhpZGUgdGhlIGRlZmF1bHQgY29udGV4dCBtZW51XHJcblxyXG5UaGlzIHJ1bGUgaXMgaW5oZXJpdGVkIGxpa2Ugbm9ybWFsIENTUyBydWxlcywgc28gbmVzdGluZyB3b3JrcyBhcyBleHBlY3RlZFxyXG4qL1xyXG5mdW5jdGlvbiBwcm9jZXNzRGVmYXVsdENvbnRleHRNZW51KGV2ZW50KSB7XHJcbiAgICAvLyBEZWJ1ZyBidWlsZHMgYWx3YXlzIHNob3cgdGhlIG1lbnVcclxuICAgIGlmIChERUJVRykge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBQcm9jZXNzIGRlZmF1bHQgY29udGV4dCBtZW51XHJcbiAgICBjb25zdCBlbGVtZW50ID0gZXZlbnQudGFyZ2V0O1xyXG4gICAgY29uc3QgY29tcHV0ZWRTdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xyXG4gICAgY29uc3QgZGVmYXVsdENvbnRleHRNZW51QWN0aW9uID0gY29tcHV0ZWRTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKFwiLS1kZWZhdWx0LWNvbnRleHRtZW51XCIpLnRyaW0oKTtcclxuICAgIHN3aXRjaCAoZGVmYXVsdENvbnRleHRNZW51QWN0aW9uKSB7XHJcbiAgICAgICAgY2FzZSBcInNob3dcIjpcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIGNhc2UgXCJoaWRlXCI6XHJcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAvLyBDaGVjayBpZiBjb250ZW50RWRpdGFibGUgaXMgdHJ1ZVxyXG4gICAgICAgICAgICBpZiAoZWxlbWVudC5pc0NvbnRlbnRFZGl0YWJsZSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBDaGVjayBpZiB0ZXh0IGhhcyBiZWVuIHNlbGVjdGVkXHJcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcclxuICAgICAgICAgICAgY29uc3QgaGFzU2VsZWN0aW9uID0gKHNlbGVjdGlvbi50b1N0cmluZygpLmxlbmd0aCA+IDApXHJcbiAgICAgICAgICAgIGlmIChoYXNTZWxlY3Rpb24pIHtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZWN0aW9uLnJhbmdlQ291bnQ7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoaSk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVjdHMgPSByYW5nZS5nZXRDbGllbnRSZWN0cygpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgcmVjdHMubGVuZ3RoOyBqKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVjdCA9IHJlY3RzW2pdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChyZWN0LmxlZnQsIHJlY3QudG9wKSA9PT0gZWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHRhZ25hbWUgaXMgaW5wdXQgb3IgdGV4dGFyZWFcclxuICAgICAgICAgICAgaWYgKGVsZW1lbnQudGFnTmFtZSA9PT0gXCJJTlBVVFwiIHx8IGVsZW1lbnQudGFnTmFtZSA9PT0gXCJURVhUQVJFQVwiKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaGFzU2VsZWN0aW9uIHx8ICghZWxlbWVudC5yZWFkT25seSAmJiAhZWxlbWVudC5kaXNhYmxlZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGhpZGUgZGVmYXVsdCBjb250ZXh0IG1lbnVcclxuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgIH1cclxufVxyXG4iLCAiXHJcbmltcG9ydCB7RW1pdCwgV2FpbHNFdmVudH0gZnJvbSBcIi4vZXZlbnRzXCI7XHJcbmltcG9ydCB7UXVlc3Rpb259IGZyb20gXCIuL2RpYWxvZ3NcIjtcclxuXHJcbmZ1bmN0aW9uIHNlbmRFdmVudChldmVudE5hbWUsIGRhdGE9bnVsbCkge1xyXG4gICAgbGV0IGV2ZW50ID0gbmV3IFdhaWxzRXZlbnQoZXZlbnROYW1lLCBkYXRhKTtcclxuICAgIEVtaXQoZXZlbnQpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRXTUxFdmVudExpc3RlbmVycygpIHtcclxuICAgIGNvbnN0IGVsZW1lbnRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW3dtbC1ldmVudF0nKTtcclxuICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICBjb25zdCBldmVudFR5cGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLWV2ZW50Jyk7XHJcbiAgICAgICAgY29uc3QgY29uZmlybSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd3bWwtY29uZmlybScpO1xyXG4gICAgICAgIGNvbnN0IHRyaWdnZXIgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLXRyaWdnZXInKSB8fCBcImNsaWNrXCI7XHJcblxyXG4gICAgICAgIGxldCBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKGNvbmZpcm0pIHtcclxuICAgICAgICAgICAgICAgIFF1ZXN0aW9uKHtUaXRsZTogXCJDb25maXJtXCIsIE1lc3NhZ2U6Y29uZmlybSwgRGV0YWNoZWQ6IGZhbHNlLCBCdXR0b25zOlt7TGFiZWw6XCJZZXNcIn0se0xhYmVsOlwiTm9cIiwgSXNEZWZhdWx0OnRydWV9XX0pLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT09IFwiTm9cIikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZW5kRXZlbnQoZXZlbnRUeXBlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBzZW5kRXZlbnQoZXZlbnRUeXBlKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vIFJlbW92ZSBleGlzdGluZyBsaXN0ZW5lcnNcclxuXHJcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKHRyaWdnZXIsIGNhbGxiYWNrKTtcclxuXHJcbiAgICAgICAgLy8gQWRkIG5ldyBsaXN0ZW5lclxyXG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcih0cmlnZ2VyLCBjYWxsYmFjayk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gY2FsbFdpbmRvd01ldGhvZChtZXRob2QpIHtcclxuICAgIGlmICh3YWlscy5XaW5kb3dbbWV0aG9kXSA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgY29uc29sZS5sb2coXCJXaW5kb3cgbWV0aG9kIFwiICsgbWV0aG9kICsgXCIgbm90IGZvdW5kXCIpO1xyXG4gICAgfVxyXG4gICAgd2FpbHMuV2luZG93W21ldGhvZF0oKTtcclxufVxyXG5cclxuZnVuY3Rpb24gYWRkV01MV2luZG93TGlzdGVuZXJzKCkge1xyXG4gICAgY29uc3QgZWxlbWVudHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdbd21sLXdpbmRvd10nKTtcclxuICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICBjb25zdCB3aW5kb3dNZXRob2QgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLXdpbmRvdycpO1xyXG4gICAgICAgIGNvbnN0IGNvbmZpcm0gPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLWNvbmZpcm0nKTtcclxuICAgICAgICBjb25zdCB0cmlnZ2VyID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3dtbC10cmlnZ2VyJykgfHwgXCJjbGlja1wiO1xyXG5cclxuICAgICAgICBsZXQgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChjb25maXJtKSB7XHJcbiAgICAgICAgICAgICAgICBRdWVzdGlvbih7VGl0bGU6IFwiQ29uZmlybVwiLCBNZXNzYWdlOmNvbmZpcm0sIEJ1dHRvbnM6W3tMYWJlbDpcIlllc1wifSx7TGFiZWw6XCJOb1wiLCBJc0RlZmF1bHQ6dHJ1ZX1dfSkudGhlbihmdW5jdGlvbiAocmVzdWx0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPT0gXCJOb1wiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxXaW5kb3dNZXRob2Qod2luZG93TWV0aG9kKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYWxsV2luZG93TWV0aG9kKHdpbmRvd01ldGhvZCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLy8gUmVtb3ZlIGV4aXN0aW5nIGxpc3RlbmVyc1xyXG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcih0cmlnZ2VyLCBjYWxsYmFjayk7XHJcblxyXG4gICAgICAgIC8vIEFkZCBuZXcgbGlzdGVuZXJcclxuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIodHJpZ2dlciwgY2FsbGJhY2spO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGFkZFdNTE9wZW5Ccm93c2VyTGlzdGVuZXIoKSB7XHJcbiAgICBjb25zdCBlbGVtZW50cyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ1t3bWwtb3BlbnVybF0nKTtcclxuICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICBjb25zdCB1cmwgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLW9wZW51cmwnKTtcclxuICAgICAgICBjb25zdCBjb25maXJtID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3dtbC1jb25maXJtJyk7XHJcbiAgICAgICAgY29uc3QgdHJpZ2dlciA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd3bWwtdHJpZ2dlcicpIHx8IFwiY2xpY2tcIjtcclxuXHJcbiAgICAgICAgbGV0IGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAoY29uZmlybSkge1xyXG4gICAgICAgICAgICAgICAgUXVlc3Rpb24oe1RpdGxlOiBcIkNvbmZpcm1cIiwgTWVzc2FnZTpjb25maXJtLCBCdXR0b25zOlt7TGFiZWw6XCJZZXNcIn0se0xhYmVsOlwiTm9cIiwgSXNEZWZhdWx0OnRydWV9XX0pLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT09IFwiTm9cIikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2b2lkIHdhaWxzLkJyb3dzZXIuT3BlblVSTCh1cmwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZvaWQgd2FpbHMuQnJvd3Nlci5PcGVuVVJMKHVybCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLy8gUmVtb3ZlIGV4aXN0aW5nIGxpc3RlbmVyc1xyXG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcih0cmlnZ2VyLCBjYWxsYmFjayk7XHJcblxyXG4gICAgICAgIC8vIEFkZCBuZXcgbGlzdGVuZXJcclxuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIodHJpZ2dlciwgY2FsbGJhY2spO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiByZWxvYWRXTUwoKSB7XHJcbiAgICBhZGRXTUxFdmVudExpc3RlbmVycygpO1xyXG4gICAgYWRkV01MV2luZG93TGlzdGVuZXJzKCk7XHJcbiAgICBhZGRXTUxPcGVuQnJvd3Nlckxpc3RlbmVyKCk7XHJcbn1cclxuIiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbi8vIGRlZmluZWQgaW4gdGhlIFRhc2tmaWxlXHJcbmV4cG9ydCBsZXQgaW52b2tlID0gZnVuY3Rpb24oaW5wdXQpIHtcclxuICAgIGlmKFdJTkRPV1MpIHtcclxuICAgICAgICBjaHJvbWUud2Vidmlldy5wb3N0TWVzc2FnZShpbnB1dCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIHdlYmtpdC5tZXNzYWdlSGFuZGxlcnMuZXh0ZXJuYWwucG9zdE1lc3NhZ2UoaW5wdXQpO1xyXG4gICAgfVxyXG59XHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcblxyXG5sZXQgZmxhZ3MgPSBuZXcgTWFwKCk7XHJcblxyXG5mdW5jdGlvbiBjb252ZXJ0VG9NYXAob2JqKSB7XHJcbiAgICBjb25zdCBtYXAgPSBuZXcgTWFwKCk7XHJcblxyXG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMob2JqKSkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIG1hcC5zZXQoa2V5LCBjb252ZXJ0VG9NYXAodmFsdWUpKTsgLy8gUmVjdXJzaXZlbHkgY29udmVydCBuZXN0ZWQgb2JqZWN0XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgbWFwLnNldChrZXksIHZhbHVlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG1hcDtcclxufVxyXG5cclxuZmV0Y2goXCIvd2FpbHMvZmxhZ3NcIikudGhlbigocmVzcG9uc2UpID0+IHtcclxuICAgIHJlc3BvbnNlLmpzb24oKS50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgICAgZmxhZ3MgPSBjb252ZXJ0VG9NYXAoZGF0YSk7XHJcbiAgICB9KTtcclxufSk7XHJcblxyXG5cclxuZnVuY3Rpb24gZ2V0VmFsdWVGcm9tTWFwKGtleVN0cmluZykge1xyXG4gICAgY29uc3Qga2V5cyA9IGtleVN0cmluZy5zcGxpdCgnLicpO1xyXG4gICAgbGV0IHZhbHVlID0gZmxhZ3M7XHJcblxyXG4gICAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xyXG4gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIE1hcCkge1xyXG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLmdldChrZXkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHZhbHVlID0gdmFsdWVba2V5XTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdmFsdWU7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBHZXRGbGFnKGtleVN0cmluZykge1xyXG4gICAgcmV0dXJuIGdldFZhbHVlRnJvbU1hcChrZXlTdHJpbmcpO1xyXG59XHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcblxyXG5pbXBvcnQge2ludm9rZX0gZnJvbSBcIi4vaW52b2tlXCI7XHJcbmltcG9ydCB7R2V0RmxhZ30gZnJvbSBcIi4vZmxhZ3NcIjtcclxuXHJcbmxldCBzaG91bGREcmFnID0gZmFsc2U7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZHJhZ1Rlc3QoZSkge1xyXG4gICAgbGV0IHZhbCA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGUudGFyZ2V0KS5nZXRQcm9wZXJ0eVZhbHVlKFwiLS13ZWJraXQtYXBwLXJlZ2lvblwiKTtcclxuICAgIGlmICh2YWwpIHtcclxuICAgICAgICB2YWwgPSB2YWwudHJpbSgpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh2YWwgIT09IFwiZHJhZ1wiKSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIE9ubHkgcHJvY2VzcyB0aGUgcHJpbWFyeSBidXR0b25cclxuICAgIGlmIChlLmJ1dHRvbnMgIT09IDEpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGUuZGV0YWlsID09PSAxO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gc2V0dXBEcmFnKCkge1xyXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIG9uTW91c2VEb3duKTtcclxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBvbk1vdXNlTW92ZSk7XHJcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIG9uTW91c2VVcCk7XHJcbn1cclxuXHJcbmxldCByZXNpemVFZGdlID0gbnVsbDtcclxubGV0IHJlc2l6YWJsZSA9IGZhbHNlO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHNldFJlc2l6YWJsZSh2YWx1ZSkge1xyXG4gICAgcmVzaXphYmxlID0gdmFsdWU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHRlc3RSZXNpemUoZSkge1xyXG4gICAgaWYoIHJlc2l6ZUVkZ2UgKSB7XHJcbiAgICAgICAgaW52b2tlKFwicmVzaXplOlwiICsgcmVzaXplRWRnZSk7XHJcbiAgICAgICAgcmV0dXJuIHRydWVcclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZTtcclxufVxyXG5cclxuZnVuY3Rpb24gb25Nb3VzZURvd24oZSkge1xyXG5cclxuICAgIC8vIENoZWNrIGZvciByZXNpemluZyBvbiBXaW5kb3dzXHJcbiAgICBpZiggV0lORE9XUyApIHtcclxuICAgICAgICBpZiAodGVzdFJlc2l6ZSgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAoZHJhZ1Rlc3QoZSkpIHtcclxuICAgICAgICAvLyBJZ25vcmUgZHJhZyBvbiBzY3JvbGxiYXJzXHJcbiAgICAgICAgaWYgKGUub2Zmc2V0WCA+IGUudGFyZ2V0LmNsaWVudFdpZHRoIHx8IGUub2Zmc2V0WSA+IGUudGFyZ2V0LmNsaWVudEhlaWdodCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHNob3VsZERyYWcgPSB0cnVlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICBzaG91bGREcmFnID0gZmFsc2U7XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIG9uTW91c2VVcChlKSB7XHJcbiAgICBsZXQgbW91c2VQcmVzc2VkID0gZS5idXR0b25zICE9PSB1bmRlZmluZWQgPyBlLmJ1dHRvbnMgOiBlLndoaWNoO1xyXG4gICAgaWYgKG1vdXNlUHJlc3NlZCA+IDApIHtcclxuICAgICAgICBlbmREcmFnKCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBlbmREcmFnKCkge1xyXG4gICAgZG9jdW1lbnQuYm9keS5zdHlsZS5jdXJzb3IgPSAnZGVmYXVsdCc7XHJcbiAgICBzaG91bGREcmFnID0gZmFsc2U7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNldFJlc2l6ZShjdXJzb3IpIHtcclxuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5jdXJzb3IgPSBjdXJzb3IgfHwgZGVmYXVsdEN1cnNvcjtcclxuICAgIHJlc2l6ZUVkZ2UgPSBjdXJzb3I7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIG9uTW91c2VNb3ZlKGUpIHtcclxuICAgIGlmIChzaG91bGREcmFnKSB7XHJcbiAgICAgICAgc2hvdWxkRHJhZyA9IGZhbHNlO1xyXG4gICAgICAgIGxldCBtb3VzZVByZXNzZWQgPSBlLmJ1dHRvbnMgIT09IHVuZGVmaW5lZCA/IGUuYnV0dG9ucyA6IGUud2hpY2g7XHJcbiAgICAgICAgaWYgKG1vdXNlUHJlc3NlZCA+IDApIHtcclxuICAgICAgICAgICAgaW52b2tlKFwiZHJhZ1wiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChXSU5ET1dTKSB7XHJcbiAgICAgICAgaWYgKHJlc2l6YWJsZSkge1xyXG4gICAgICAgICAgICBoYW5kbGVSZXNpemUoZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG5sZXQgZGVmYXVsdEN1cnNvciA9IFwiYXV0b1wiO1xyXG5cclxuZnVuY3Rpb24gaGFuZGxlUmVzaXplKGUpIHtcclxuICAgIGxldCByZXNpemVIYW5kbGVIZWlnaHQgPSBHZXRGbGFnKFwic3lzdGVtLnJlc2l6ZUhhbmRsZUhlaWdodFwiKSB8fCA1O1xyXG4gICAgbGV0IHJlc2l6ZUhhbmRsZVdpZHRoID0gR2V0RmxhZyhcInN5c3RlbS5yZXNpemVIYW5kbGVXaWR0aFwiKSB8fCA1O1xyXG5cclxuICAgIC8vIEV4dHJhIHBpeGVscyBmb3IgdGhlIGNvcm5lciBhcmVhc1xyXG4gICAgbGV0IGNvcm5lckV4dHJhID0gR2V0RmxhZyhcInJlc2l6ZUNvcm5lckV4dHJhXCIpIHx8IDEwO1xyXG5cclxuICAgIGxldCByaWdodEJvcmRlciA9IHdpbmRvdy5vdXRlcldpZHRoIC0gZS5jbGllbnRYIDwgcmVzaXplSGFuZGxlV2lkdGg7XHJcbiAgICBsZXQgbGVmdEJvcmRlciA9IGUuY2xpZW50WCA8IHJlc2l6ZUhhbmRsZVdpZHRoO1xyXG4gICAgbGV0IHRvcEJvcmRlciA9IGUuY2xpZW50WSA8IHJlc2l6ZUhhbmRsZUhlaWdodDtcclxuICAgIGxldCBib3R0b21Cb3JkZXIgPSB3aW5kb3cub3V0ZXJIZWlnaHQgLSBlLmNsaWVudFkgPCByZXNpemVIYW5kbGVIZWlnaHQ7XHJcblxyXG4gICAgLy8gQWRqdXN0IGZvciBjb3JuZXJzXHJcbiAgICBsZXQgcmlnaHRDb3JuZXIgPSB3aW5kb3cub3V0ZXJXaWR0aCAtIGUuY2xpZW50WCA8IChyZXNpemVIYW5kbGVXaWR0aCArIGNvcm5lckV4dHJhKTtcclxuICAgIGxldCBsZWZ0Q29ybmVyID0gZS5jbGllbnRYIDwgKHJlc2l6ZUhhbmRsZVdpZHRoICsgY29ybmVyRXh0cmEpO1xyXG4gICAgbGV0IHRvcENvcm5lciA9IGUuY2xpZW50WSA8IChyZXNpemVIYW5kbGVIZWlnaHQgKyBjb3JuZXJFeHRyYSk7XHJcbiAgICBsZXQgYm90dG9tQ29ybmVyID0gd2luZG93Lm91dGVySGVpZ2h0IC0gZS5jbGllbnRZIDwgKHJlc2l6ZUhhbmRsZUhlaWdodCArIGNvcm5lckV4dHJhKTtcclxuXHJcbiAgICAvLyBJZiB3ZSBhcmVuJ3Qgb24gYW4gZWRnZSwgYnV0IHdlcmUsIHJlc2V0IHRoZSBjdXJzb3IgdG8gZGVmYXVsdFxyXG4gICAgaWYgKCFsZWZ0Qm9yZGVyICYmICFyaWdodEJvcmRlciAmJiAhdG9wQm9yZGVyICYmICFib3R0b21Cb3JkZXIgJiYgcmVzaXplRWRnZSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgc2V0UmVzaXplKCk7XHJcbiAgICB9XHJcbiAgICAvLyBBZGp1c3RlZCBmb3IgY29ybmVyIGFyZWFzXHJcbiAgICBlbHNlIGlmIChyaWdodENvcm5lciAmJiBib3R0b21Db3JuZXIpIHNldFJlc2l6ZShcInNlLXJlc2l6ZVwiKTtcclxuICAgIGVsc2UgaWYgKGxlZnRDb3JuZXIgJiYgYm90dG9tQ29ybmVyKSBzZXRSZXNpemUoXCJzdy1yZXNpemVcIik7XHJcbiAgICBlbHNlIGlmIChsZWZ0Q29ybmVyICYmIHRvcENvcm5lcikgc2V0UmVzaXplKFwibnctcmVzaXplXCIpO1xyXG4gICAgZWxzZSBpZiAodG9wQ29ybmVyICYmIHJpZ2h0Q29ybmVyKSBzZXRSZXNpemUoXCJuZS1yZXNpemVcIik7XHJcbiAgICBlbHNlIGlmIChsZWZ0Qm9yZGVyKSBzZXRSZXNpemUoXCJ3LXJlc2l6ZVwiKTtcclxuICAgIGVsc2UgaWYgKHRvcEJvcmRlcikgc2V0UmVzaXplKFwibi1yZXNpemVcIik7XHJcbiAgICBlbHNlIGlmIChib3R0b21Cb3JkZXIpIHNldFJlc2l6ZShcInMtcmVzaXplXCIpO1xyXG4gICAgZWxzZSBpZiAocmlnaHRCb3JkZXIpIHNldFJlc2l6ZShcImUtcmVzaXplXCIpO1xyXG59XHJcbiIsICIvKlxyXG4gXyAgICAgX18gICAgIF8gX19cclxufCB8ICAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcblxyXG5pbXBvcnQgKiBhcyBDbGlwYm9hcmQgZnJvbSAnLi9jbGlwYm9hcmQnO1xyXG5pbXBvcnQgKiBhcyBBcHBsaWNhdGlvbiBmcm9tICcuL2FwcGxpY2F0aW9uJztcclxuaW1wb3J0ICogYXMgU2NyZWVucyBmcm9tICcuL3NjcmVlbnMnO1xyXG5pbXBvcnQgKiBhcyBTeXN0ZW0gZnJvbSAnLi9zeXN0ZW0nO1xyXG5pbXBvcnQgKiBhcyBCcm93c2VyIGZyb20gJy4vYnJvd3Nlcic7XHJcbmltcG9ydCB7UGx1Z2luLCBDYWxsLCBjYWxsRXJyb3JDYWxsYmFjaywgY2FsbENhbGxiYWNrLCBDYWxsQnlJRCwgQ2FsbEJ5TmFtZX0gZnJvbSBcIi4vY2FsbHNcIjtcclxuaW1wb3J0IHtjbGllbnRJZH0gZnJvbSAnLi9ydW50aW1lJztcclxuaW1wb3J0IHtuZXdXaW5kb3d9IGZyb20gXCIuL3dpbmRvd1wiO1xyXG5pbXBvcnQge2Rpc3BhdGNoV2FpbHNFdmVudCwgRW1pdCwgT2ZmLCBPZmZBbGwsIE9uLCBPbmNlLCBPbk11bHRpcGxlfSBmcm9tIFwiLi9ldmVudHNcIjtcclxuaW1wb3J0IHtkaWFsb2dDYWxsYmFjaywgZGlhbG9nRXJyb3JDYWxsYmFjaywgRXJyb3IsIEluZm8sIE9wZW5GaWxlLCBRdWVzdGlvbiwgU2F2ZUZpbGUsIFdhcm5pbmcsfSBmcm9tIFwiLi9kaWFsb2dzXCI7XHJcbmltcG9ydCB7c2V0dXBDb250ZXh0TWVudXN9IGZyb20gXCIuL2NvbnRleHRtZW51XCI7XHJcbmltcG9ydCB7cmVsb2FkV01MfSBmcm9tIFwiLi93bWxcIjtcclxuaW1wb3J0IHtzZXR1cERyYWcsIGVuZERyYWcsIHNldFJlc2l6YWJsZX0gZnJvbSBcIi4vZHJhZ1wiO1xyXG5cclxud2luZG93LndhaWxzID0ge1xyXG4gICAgLi4ubmV3UnVudGltZShudWxsKSxcclxuICAgIENhcGFiaWxpdGllczoge30sXHJcbiAgICBjbGllbnRJZDogY2xpZW50SWQsXHJcbn07XHJcblxyXG5mZXRjaChcIi93YWlscy9jYXBhYmlsaXRpZXNcIikudGhlbigocmVzcG9uc2UpID0+IHtcclxuICAgIHJlc3BvbnNlLmpzb24oKS50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgICAgd2luZG93LndhaWxzLkNhcGFiaWxpdGllcyA9IGRhdGE7XHJcbiAgICB9KTtcclxufSk7XHJcblxyXG4vLyBJbnRlcm5hbCB3YWlscyBlbmRwb2ludHNcclxud2luZG93Ll93YWlscyA9IHtcclxuICAgIGRpYWxvZ0NhbGxiYWNrLFxyXG4gICAgZGlhbG9nRXJyb3JDYWxsYmFjayxcclxuICAgIGRpc3BhdGNoV2FpbHNFdmVudCxcclxuICAgIGNhbGxDYWxsYmFjayxcclxuICAgIGNhbGxFcnJvckNhbGxiYWNrLFxyXG4gICAgZW5kRHJhZyxcclxuICAgIHNldFJlc2l6YWJsZSxcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBuZXdSdW50aW1lKHdpbmRvd05hbWUpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgQ2xpcGJvYXJkOiB7XHJcbiAgICAgICAgICAgIC4uLkNsaXBib2FyZFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgQXBwbGljYXRpb246IHtcclxuICAgICAgICAgICAgLi4uQXBwbGljYXRpb24sXHJcbiAgICAgICAgICAgIEdldFdpbmRvd0J5TmFtZSh3aW5kb3dOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3UnVudGltZSh3aW5kb3dOYW1lKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgU3lzdGVtLFxyXG4gICAgICAgIFNjcmVlbnMsXHJcbiAgICAgICAgQnJvd3NlcixcclxuICAgICAgICBDYWxsLFxyXG4gICAgICAgIENhbGxCeUlELFxyXG4gICAgICAgIENhbGxCeU5hbWUsXHJcbiAgICAgICAgUGx1Z2luLFxyXG4gICAgICAgIFdNTDoge1xyXG4gICAgICAgICAgICBSZWxvYWQ6IHJlbG9hZFdNTCxcclxuICAgICAgICB9LFxyXG4gICAgICAgIERpYWxvZzoge1xyXG4gICAgICAgICAgICBJbmZvLFxyXG4gICAgICAgICAgICBXYXJuaW5nLFxyXG4gICAgICAgICAgICBFcnJvcixcclxuICAgICAgICAgICAgUXVlc3Rpb24sXHJcbiAgICAgICAgICAgIE9wZW5GaWxlLFxyXG4gICAgICAgICAgICBTYXZlRmlsZSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIEV2ZW50czoge1xyXG4gICAgICAgICAgICBFbWl0LFxyXG4gICAgICAgICAgICBPbixcclxuICAgICAgICAgICAgT25jZSxcclxuICAgICAgICAgICAgT25NdWx0aXBsZSxcclxuICAgICAgICAgICAgT2ZmLFxyXG4gICAgICAgICAgICBPZmZBbGwsXHJcbiAgICAgICAgfSxcclxuICAgICAgICBXaW5kb3c6IG5ld1dpbmRvdyh3aW5kb3dOYW1lKSxcclxuICAgIH07XHJcbn1cclxuXHJcbmlmIChERUJVRykge1xyXG4gICAgY29uc29sZS5sb2coXCJXYWlscyB2My4wLjAgRGVidWcgTW9kZSBFbmFibGVkXCIpO1xyXG59XHJcblxyXG5zZXR1cENvbnRleHRNZW51cygpO1xyXG5zZXR1cERyYWcoKTtcclxuXHJcbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGZ1bmN0aW9uKCkge1xyXG4gICAg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QSxJQUNoQyxDQUFDO0FBQUEsRUFDTCxDQUFDO0FBR0QsU0FBTyxTQUFTO0FBQUEsSUFDWjtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLEVBQ0o7QUFFTyxXQUFTLFdBQVcsWUFBWTtBQUNuQyxXQUFPO0FBQUEsTUFDSCxXQUFXO0FBQUEsUUFDUCxHQUFHO0FBQUEsTUFDUDtBQUFBLE1BQ0EsYUFBYTtBQUFBLFFBQ1QsR0FBRztBQUFBLFFBQ0gsZ0JBQWdCQyxhQUFZO0FBQ3hCLGlCQUFPLFdBQVdBLFdBQVU7QUFBQSxRQUNoQztBQUFBLE1BQ0o7QUFBQSxNQUNBO0FBQUEsTUFDQTtBQUFBLE1BQ0E7QUFBQSxNQUNBO0FBQUEsTUFDQTtBQUFBLE1BQ0E7QUFBQSxNQUNBO0FBQUEsTUFDQSxLQUFLO0FBQUEsUUFDRCxRQUFRO0FBQUEsTUFDWjtBQUFBLE1BQ0EsUUFBUTtBQUFBLFFBQ0o7QUFBQSxRQUNBO0FBQUEsUUFDQSxPQUFBQztBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLE1BQ0o7QUFBQSxNQUNBLFFBQVE7QUFBQSxRQUNKO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxNQUNKO0FBQUEsTUFDQSxRQUFRLFVBQVUsVUFBVTtBQUFBLElBQ2hDO0FBQUEsRUFDSjtBQUVBLE1BQUksTUFBTztBQUNQLFlBQVEsSUFBSSxpQ0FBaUM7QUFBQSxFQUNqRDtBQUVBLG9CQUFrQjtBQUNsQixZQUFVO0FBRVYsV0FBUyxpQkFBaUIsb0JBQW9CLFdBQVc7QUFDckQsY0FBVTtBQUFBLEVBQ2QsQ0FBQzsiLAogICJuYW1lcyI6IFsiY2FsbCIsICJjYWxsIiwgImNhbGwiLCAiY2FsbCIsICJjYWxsIiwgImNhbGwiLCAicmVzaXphYmxlIiwgImNhbGwiLCAiZXZlbnROYW1lIiwgImNhbGwiLCAiZ2VuZXJhdGVJRCIsICJFcnJvciIsICJjYWxsIiwgIndpbmRvd05hbWUiLCAiRXJyb3IiXQp9Cg== diff --git a/v3/internal/runtime/runtime_debug_desktop_linux.js b/v3/internal/runtime/runtime_debug_desktop_linux.js deleted file mode 100644 index 3e0861b89b2..00000000000 --- a/v3/internal/runtime/runtime_debug_desktop_linux.js +++ /dev/null @@ -1,873 +0,0 @@ -(() => { - var __defProp = Object.defineProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - - // desktop/clipboard.js - var clipboard_exports = {}; - __export(clipboard_exports, { - SetText: () => SetText, - Text: () => Text - }); - - // node_modules/nanoid/non-secure/index.js - var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"; - var nanoid = (size = 21) => { - let id = ""; - let i = size; - while (i--) { - id += urlAlphabet[Math.random() * 64 | 0]; - } - return id; - }; - - // desktop/runtime.js - var runtimeURL = window.location.origin + "/wails/runtime"; - var objectNames = { - Call: 0, - Clipboard: 1, - Application: 2, - Events: 3, - ContextMenu: 4, - Dialog: 5, - Window: 6, - Screens: 7, - System: 8, - Browser: 9 - }; - var clientId = nanoid(); - function runtimeCallWithID(objectID, method, windowName, args) { - let url = new URL(runtimeURL); - url.searchParams.append("object", objectID); - url.searchParams.append("method", method); - let fetchOptions = { - headers: {} - }; - if (windowName) { - fetchOptions.headers["x-wails-window-name"] = windowName; - } - if (args) { - url.searchParams.append("args", JSON.stringify(args)); - } - fetchOptions.headers["x-wails-client-id"] = clientId; - return new Promise((resolve, reject) => { - fetch(url, fetchOptions).then((response) => { - if (response.ok) { - if (response.headers.get("Content-Type") && response.headers.get("Content-Type").indexOf("application/json") !== -1) { - return response.json(); - } else { - return response.text(); - } - } - reject(Error(response.statusText)); - }).then((data) => resolve(data)).catch((error) => reject(error)); - }); - } - function newRuntimeCallerWithID(object, windowName) { - return function(method, args = null) { - return runtimeCallWithID(object, method, windowName, args); - }; - } - - // desktop/clipboard.js - var call = newRuntimeCallerWithID(objectNames.Clipboard); - var ClipboardSetText = 0; - var ClipboardText = 1; - function SetText(text) { - void call(ClipboardSetText, { text }); - } - function Text() { - return call(ClipboardText); - } - - // desktop/application.js - var application_exports = {}; - __export(application_exports, { - Hide: () => Hide, - Quit: () => Quit, - Show: () => Show - }); - var call2 = newRuntimeCallerWithID(objectNames.Application); - var methods = { - Hide: 0, - Show: 1, - Quit: 2 - }; - function Hide() { - void call2(methods.Hide); - } - function Show() { - void call2(methods.Show); - } - function Quit() { - void call2(methods.Quit); - } - - // desktop/screens.js - var screens_exports = {}; - __export(screens_exports, { - GetAll: () => GetAll, - GetCurrent: () => GetCurrent, - GetPrimary: () => GetPrimary - }); - var call3 = newRuntimeCallerWithID(objectNames.Screens); - var ScreensGetAll = 0; - var ScreensGetPrimary = 1; - var ScreensGetCurrent = 2; - function GetAll() { - return call3(ScreensGetAll); - } - function GetPrimary() { - return call3(ScreensGetPrimary); - } - function GetCurrent() { - return call3(ScreensGetCurrent); - } - - // desktop/system.js - var system_exports = {}; - __export(system_exports, { - IsDarkMode: () => IsDarkMode - }); - var call4 = newRuntimeCallerWithID(objectNames.System); - var SystemIsDarkMode = 0; - function IsDarkMode() { - return call4(SystemIsDarkMode); - } - - // desktop/browser.js - var browser_exports = {}; - __export(browser_exports, { - OpenURL: () => OpenURL - }); - var call5 = newRuntimeCallerWithID(objectNames.Browser); - var BrowserOpenURL = 0; - function OpenURL(url) { - void call5(BrowserOpenURL, { url }); - } - - // desktop/calls.js - var call6 = newRuntimeCallerWithID(objectNames.Call); - var CallBinding = 0; - var callResponses = /* @__PURE__ */ new Map(); - function generateID() { - let result; - do { - result = nanoid(); - } while (callResponses.has(result)); - return result; - } - function callCallback(id, data, isJSON) { - let p = callResponses.get(id); - if (p) { - if (isJSON) { - p.resolve(JSON.parse(data)); - } else { - p.resolve(data); - } - callResponses.delete(id); - } - } - function callErrorCallback(id, message) { - let p = callResponses.get(id); - if (p) { - p.reject(message); - callResponses.delete(id); - } - } - function callBinding(type, options) { - return new Promise((resolve, reject) => { - let id = generateID(); - options = options || {}; - options["call-id"] = id; - callResponses.set(id, { resolve, reject }); - call6(type, options).catch((error) => { - reject(error); - callResponses.delete(id); - }); - }); - } - function Call(options) { - return callBinding(CallBinding, options); - } - function CallByName(name, ...args) { - if (typeof name !== "string" || name.split(".").length !== 3) { - throw new Error("CallByName requires a string in the format 'package.struct.method'"); - } - let parts = name.split("."); - return callBinding(CallBinding, { - packageName: parts[0], - structName: parts[1], - methodName: parts[2], - args - }); - } - function CallByID(methodID, ...args) { - return callBinding(CallBinding, { - methodID, - args - }); - } - function Plugin(pluginName, methodName, ...args) { - return callBinding(CallBinding, { - packageName: "wails-plugins", - structName: pluginName, - methodName, - args - }); - } - - // desktop/window.js - var WindowCenter = 0; - var WindowSetTitle = 1; - var WindowFullscreen = 2; - var WindowUnFullscreen = 3; - var WindowSetSize = 4; - var WindowSize = 5; - var WindowSetMaxSize = 6; - var WindowSetMinSize = 7; - var WindowSetAlwaysOnTop = 8; - var WindowSetRelativePosition = 9; - var WindowRelativePosition = 10; - var WindowScreen = 11; - var WindowHide = 12; - var WindowMaximise = 13; - var WindowUnMaximise = 14; - var WindowToggleMaximise = 15; - var WindowMinimise = 16; - var WindowUnMinimise = 17; - var WindowRestore = 18; - var WindowShow = 19; - var WindowClose = 20; - var WindowSetBackgroundColour = 21; - var WindowSetResizable = 22; - var WindowWidth = 23; - var WindowHeight = 24; - var WindowZoomIn = 25; - var WindowZoomOut = 26; - var WindowZoomReset = 27; - var WindowGetZoomLevel = 28; - var WindowSetZoomLevel = 29; - function newWindow(windowName) { - let call10 = newRuntimeCallerWithID(objectNames.Window, windowName); - return { - /** - * Centers the window. - */ - Center: () => void call10(WindowCenter), - /** - * Set the window title. - * @param title - */ - SetTitle: (title) => void call10(WindowSetTitle, { title }), - /** - * Makes the window fullscreen. - */ - Fullscreen: () => void call10(WindowFullscreen), - /** - * Unfullscreen the window. - */ - UnFullscreen: () => void call10(WindowUnFullscreen), - /** - * Set the window size. - * @param {number} width The window width - * @param {number} height The window height - */ - SetSize: (width, height) => call10(WindowSetSize, { width, height }), - /** - * Get the window size. - * @returns {Promise} The window size - */ - Size: () => { - return call10(WindowSize); - }, - /** - * Set the window maximum size. - * @param {number} width - * @param {number} height - */ - SetMaxSize: (width, height) => void call10(WindowSetMaxSize, { width, height }), - /** - * Set the window minimum size. - * @param {number} width - * @param {number} height - */ - SetMinSize: (width, height) => void call10(WindowSetMinSize, { width, height }), - /** - * Set window to be always on top. - * @param {boolean} onTop Whether the window should be always on top - */ - SetAlwaysOnTop: (onTop) => void call10(WindowSetAlwaysOnTop, { alwaysOnTop: onTop }), - /** - * Set the window relative position. - * @param {number} x - * @param {number} y - */ - SetRelativePosition: (x, y) => call10(WindowSetRelativePosition, { x, y }), - /** - * Get the window position. - * @returns {Promise} The window position - */ - RelativePosition: () => { - return call10(WindowRelativePosition); - }, - /** - * Get the screen the window is on. - * @returns {Promise} - */ - Screen: () => { - return call10(WindowScreen); - }, - /** - * Hide the window - */ - Hide: () => void call10(WindowHide), - /** - * Maximise the window - */ - Maximise: () => void call10(WindowMaximise), - /** - * Show the window - */ - Show: () => void call10(WindowShow), - /** - * Close the window - */ - Close: () => void call10(WindowClose), - /** - * Toggle the window maximise state - */ - ToggleMaximise: () => void call10(WindowToggleMaximise), - /** - * Unmaximise the window - */ - UnMaximise: () => void call10(WindowUnMaximise), - /** - * Minimise the window - */ - Minimise: () => void call10(WindowMinimise), - /** - * Unminimise the window - */ - UnMinimise: () => void call10(WindowUnMinimise), - /** - * Restore the window - */ - Restore: () => void call10(WindowRestore), - /** - * Set the background colour of the window. - * @param {number} r - A value between 0 and 255 - * @param {number} g - A value between 0 and 255 - * @param {number} b - A value between 0 and 255 - * @param {number} a - A value between 0 and 255 - */ - SetBackgroundColour: (r, g, b, a) => void call10(WindowSetBackgroundColour, { r, g, b, a }), - /** - * Set whether the window can be resized or not - * @param {boolean} resizable - */ - SetResizable: (resizable2) => void call10(WindowSetResizable, { resizable: resizable2 }), - /** - * Get the window width - * @returns {Promise} - */ - Width: () => { - return call10(WindowWidth); - }, - /** - * Get the window height - * @returns {Promise} - */ - Height: () => { - return call10(WindowHeight); - }, - /** - * Zoom in the window - */ - ZoomIn: () => void call10(WindowZoomIn), - /** - * Zoom out the window - */ - ZoomOut: () => void call10(WindowZoomOut), - /** - * Reset the window zoom - */ - ZoomReset: () => void call10(WindowZoomReset), - /** - * Get the window zoom - * @returns {Promise} - */ - GetZoomLevel: () => { - return call10(WindowGetZoomLevel); - }, - /** - * Set the window zoom level - * @param {number} zoomLevel - */ - SetZoomLevel: (zoomLevel) => void call10(WindowSetZoomLevel, { zoomLevel }) - }; - } - - // desktop/events.js - var call7 = newRuntimeCallerWithID(objectNames.Events); - var EventEmit = 0; - var Listener = class { - /** - * Creates an instance of Listener. - * @param {string} eventName - * @param {function} callback - * @param {number} maxCallbacks - * @memberof Listener - */ - constructor(eventName, callback, maxCallbacks) { - this.eventName = eventName; - this.maxCallbacks = maxCallbacks || -1; - this.Callback = (data) => { - callback(data); - if (this.maxCallbacks === -1) { - return false; - } - this.maxCallbacks -= 1; - return this.maxCallbacks === 0; - }; - } - }; - var WailsEvent = class { - /** - * Creates an instance of WailsEvent. - * @param {string} name - Name of the event - * @param {any=null} data - Data associated with the event - * @memberof WailsEvent - */ - constructor(name, data = null) { - this.name = name; - this.data = data; - } - }; - var eventListeners = /* @__PURE__ */ new Map(); - function OnMultiple(eventName, callback, maxCallbacks) { - let listeners = eventListeners.get(eventName) || []; - const thisListener = new Listener(eventName, callback, maxCallbacks); - listeners.push(thisListener); - eventListeners.set(eventName, listeners); - return () => listenerOff(thisListener); - } - function On(eventName, callback) { - return OnMultiple(eventName, callback, -1); - } - function Once(eventName, callback) { - return OnMultiple(eventName, callback, 1); - } - function listenerOff(listener) { - const eventName = listener.eventName; - let listeners = eventListeners.get(eventName).filter((l) => l !== listener); - if (listeners.length === 0) { - eventListeners.delete(eventName); - } else { - eventListeners.set(eventName, listeners); - } - } - function dispatchWailsEvent(event) { - let listeners = eventListeners.get(event.name); - if (listeners) { - let toRemove = []; - listeners.forEach((listener) => { - let remove = listener.Callback(event); - if (remove) { - toRemove.push(listener); - } - }); - if (toRemove.length > 0) { - listeners = listeners.filter((l) => !toRemove.includes(l)); - if (listeners.length === 0) { - eventListeners.delete(event.name); - } else { - eventListeners.set(event.name, listeners); - } - } - } - } - function Off(eventName, ...additionalEventNames) { - let eventsToRemove = [eventName, ...additionalEventNames]; - eventsToRemove.forEach((eventName2) => { - eventListeners.delete(eventName2); - }); - } - function OffAll() { - eventListeners.clear(); - } - function Emit(event) { - void call7(EventEmit, event); - } - - // desktop/dialogs.js - var call8 = newRuntimeCallerWithID(objectNames.Dialog); - var DialogInfo = 0; - var DialogWarning = 1; - var DialogError = 2; - var DialogQuestion = 3; - var DialogOpenFile = 4; - var DialogSaveFile = 5; - var dialogResponses = /* @__PURE__ */ new Map(); - function generateID2() { - let result; - do { - result = nanoid(); - } while (dialogResponses.has(result)); - return result; - } - function dialogCallback(id, data, isJSON) { - let p = dialogResponses.get(id); - if (p) { - if (isJSON) { - p.resolve(JSON.parse(data)); - } else { - p.resolve(data); - } - dialogResponses.delete(id); - } - } - function dialogErrorCallback(id, message) { - let p = dialogResponses.get(id); - if (p) { - p.reject(message); - dialogResponses.delete(id); - } - } - function dialog(type, options) { - return new Promise((resolve, reject) => { - let id = generateID2(); - options = options || {}; - options["dialog-id"] = id; - dialogResponses.set(id, { resolve, reject }); - call8(type, options).catch((error) => { - reject(error); - dialogResponses.delete(id); - }); - }); - } - function Info(options) { - return dialog(DialogInfo, options); - } - function Warning(options) { - return dialog(DialogWarning, options); - } - function Error2(options) { - return dialog(DialogError, options); - } - function Question(options) { - return dialog(DialogQuestion, options); - } - function OpenFile(options) { - return dialog(DialogOpenFile, options); - } - function SaveFile(options) { - return dialog(DialogSaveFile, options); - } - - // desktop/contextmenu.js - var call9 = newRuntimeCallerWithID(objectNames.ContextMenu); - var ContextMenuOpen = 0; - function openContextMenu(id, x, y, data) { - void call9(ContextMenuOpen, { id, x, y, data }); - } - function setupContextMenus() { - window.addEventListener("contextmenu", contextMenuHandler); - } - function contextMenuHandler(event) { - let element = event.target; - let customContextMenu = window.getComputedStyle(element).getPropertyValue("--custom-contextmenu"); - customContextMenu = customContextMenu ? customContextMenu.trim() : ""; - if (customContextMenu) { - event.preventDefault(); - let customContextMenuData = window.getComputedStyle(element).getPropertyValue("--custom-contextmenu-data"); - openContextMenu(customContextMenu, event.clientX, event.clientY, customContextMenuData); - return; - } - processDefaultContextMenu(event); - } - function processDefaultContextMenu(event) { - if (true) { - return; - } - const element = event.target; - const computedStyle = window.getComputedStyle(element); - const defaultContextMenuAction = computedStyle.getPropertyValue("--default-contextmenu").trim(); - switch (defaultContextMenuAction) { - case "show": - return; - case "hide": - event.preventDefault(); - return; - default: - if (element.isContentEditable) { - return; - } - const selection = window.getSelection(); - const hasSelection = selection.toString().length > 0; - if (hasSelection) { - for (let i = 0; i < selection.rangeCount; i++) { - const range = selection.getRangeAt(i); - const rects = range.getClientRects(); - for (let j = 0; j < rects.length; j++) { - const rect = rects[j]; - if (document.elementFromPoint(rect.left, rect.top) === element) { - return; - } - } - } - } - if (element.tagName === "INPUT" || element.tagName === "TEXTAREA") { - if (hasSelection || !element.readOnly && !element.disabled) { - return; - } - } - event.preventDefault(); - } - } - - // desktop/wml.js - function sendEvent(eventName, data = null) { - let event = new WailsEvent(eventName, data); - Emit(event); - } - function addWMLEventListeners() { - const elements = document.querySelectorAll("[wml-event]"); - elements.forEach(function(element) { - const eventType = element.getAttribute("wml-event"); - const confirm = element.getAttribute("wml-confirm"); - const trigger = element.getAttribute("wml-trigger") || "click"; - let callback = function() { - if (confirm) { - Question({ Title: "Confirm", Message: confirm, Detached: false, Buttons: [{ Label: "Yes" }, { Label: "No", IsDefault: true }] }).then(function(result) { - if (result !== "No") { - sendEvent(eventType); - } - }); - return; - } - sendEvent(eventType); - }; - element.removeEventListener(trigger, callback); - element.addEventListener(trigger, callback); - }); - } - function callWindowMethod(method) { - if (wails.Window[method] === void 0) { - console.log("Window method " + method + " not found"); - } - wails.Window[method](); - } - function addWMLWindowListeners() { - const elements = document.querySelectorAll("[wml-window]"); - elements.forEach(function(element) { - const windowMethod = element.getAttribute("wml-window"); - const confirm = element.getAttribute("wml-confirm"); - const trigger = element.getAttribute("wml-trigger") || "click"; - let callback = function() { - if (confirm) { - Question({ Title: "Confirm", Message: confirm, Buttons: [{ Label: "Yes" }, { Label: "No", IsDefault: true }] }).then(function(result) { - if (result !== "No") { - callWindowMethod(windowMethod); - } - }); - return; - } - callWindowMethod(windowMethod); - }; - element.removeEventListener(trigger, callback); - element.addEventListener(trigger, callback); - }); - } - function addWMLOpenBrowserListener() { - const elements = document.querySelectorAll("[wml-openurl]"); - elements.forEach(function(element) { - const url = element.getAttribute("wml-openurl"); - const confirm = element.getAttribute("wml-confirm"); - const trigger = element.getAttribute("wml-trigger") || "click"; - let callback = function() { - if (confirm) { - Question({ Title: "Confirm", Message: confirm, Buttons: [{ Label: "Yes" }, { Label: "No", IsDefault: true }] }).then(function(result) { - if (result !== "No") { - void wails.Browser.OpenURL(url); - } - }); - return; - } - void wails.Browser.OpenURL(url); - }; - element.removeEventListener(trigger, callback); - element.addEventListener(trigger, callback); - }); - } - function reloadWML() { - addWMLEventListeners(); - addWMLWindowListeners(); - addWMLOpenBrowserListener(); - } - - // desktop/invoke.js - var invoke = function(input) { - if (false) { - chrome.webview.postMessage(input); - } else { - webkit.messageHandlers.external.postMessage(input); - } - }; - - // desktop/flags.js - var flags = /* @__PURE__ */ new Map(); - function convertToMap(obj) { - const map = /* @__PURE__ */ new Map(); - for (const [key, value] of Object.entries(obj)) { - if (typeof value === "object" && value !== null) { - map.set(key, convertToMap(value)); - } else { - map.set(key, value); - } - } - return map; - } - fetch("/wails/flags").then((response) => { - response.json().then((data) => { - flags = convertToMap(data); - }); - }); - - // desktop/drag.js - var shouldDrag = false; - function dragTest(e) { - let val = window.getComputedStyle(e.target).getPropertyValue("--webkit-app-region"); - if (val) { - val = val.trim(); - } - if (val !== "drag") { - return false; - } - if (e.buttons !== 1) { - return false; - } - return e.detail === 1; - } - function setupDrag() { - window.addEventListener("mousedown", onMouseDown); - window.addEventListener("mousemove", onMouseMove); - window.addEventListener("mouseup", onMouseUp); - } - var resizable = false; - function setResizable(value) { - resizable = value; - } - function onMouseDown(e) { - if (false) { - if (testResize()) { - return; - } - } - if (dragTest(e)) { - if (e.offsetX > e.target.clientWidth || e.offsetY > e.target.clientHeight) { - return; - } - shouldDrag = true; - } else { - shouldDrag = false; - } - } - function onMouseUp(e) { - let mousePressed = e.buttons !== void 0 ? e.buttons : e.which; - if (mousePressed > 0) { - endDrag(); - } - } - function endDrag() { - document.body.style.cursor = "default"; - shouldDrag = false; - } - function onMouseMove(e) { - if (shouldDrag) { - shouldDrag = false; - let mousePressed = e.buttons !== void 0 ? e.buttons : e.which; - if (mousePressed > 0) { - invoke("drag"); - } - return; - } - if (false) { - if (resizable) { - handleResize(e); - } - } - } - - // desktop/main.js - window.wails = { - ...newRuntime(null), - Capabilities: {}, - clientId - }; - fetch("/wails/capabilities").then((response) => { - response.json().then((data) => { - window.wails.Capabilities = data; - }); - }); - window._wails = { - dialogCallback, - dialogErrorCallback, - dispatchWailsEvent, - callCallback, - callErrorCallback, - endDrag, - setResizable - }; - function newRuntime(windowName) { - return { - Clipboard: { - ...clipboard_exports - }, - Application: { - ...application_exports, - GetWindowByName(windowName2) { - return newRuntime(windowName2); - } - }, - System: system_exports, - Screens: screens_exports, - Browser: browser_exports, - Call, - CallByID, - CallByName, - Plugin, - WML: { - Reload: reloadWML - }, - Dialog: { - Info, - Warning, - Error: Error2, - Question, - OpenFile, - SaveFile - }, - Events: { - Emit, - On, - Once, - OnMultiple, - Off, - OffAll - }, - Window: newWindow(windowName) - }; - } - if (true) { - console.log("Wails v3.0.0 Debug Mode Enabled"); - } - setupContextMenus(); - setupDrag(); - document.addEventListener("DOMContentLoaded", function() { - reloadWML(); - }); -})(); -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiZGVza3RvcC9jbGlwYm9hcmQuanMiLCAibm9kZV9tb2R1bGVzL25hbm9pZC9ub24tc2VjdXJlL2luZGV4LmpzIiwgImRlc2t0b3AvcnVudGltZS5qcyIsICJkZXNrdG9wL2FwcGxpY2F0aW9uLmpzIiwgImRlc2t0b3Avc2NyZWVucy5qcyIsICJkZXNrdG9wL3N5c3RlbS5qcyIsICJkZXNrdG9wL2Jyb3dzZXIuanMiLCAiZGVza3RvcC9jYWxscy5qcyIsICJkZXNrdG9wL3dpbmRvdy5qcyIsICJkZXNrdG9wL2V2ZW50cy5qcyIsICJkZXNrdG9wL2RpYWxvZ3MuanMiLCAiZGVza3RvcC9jb250ZXh0bWVudS5qcyIsICJkZXNrdG9wL3dtbC5qcyIsICJkZXNrdG9wL2ludm9rZS5qcyIsICJkZXNrdG9wL2ZsYWdzLmpzIiwgImRlc2t0b3AvZHJhZy5qcyIsICJkZXNrdG9wL21haW4uanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmxldCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5DbGlwYm9hcmQpO1xyXG5cclxubGV0IENsaXBib2FyZFNldFRleHQgPSAwO1xyXG5sZXQgQ2xpcGJvYXJkVGV4dCA9IDE7XHJcblxyXG4vKipcclxuICogU2V0IHRoZSBDbGlwYm9hcmQgdGV4dFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIFNldFRleHQodGV4dCkge1xyXG4gICAgdm9pZCBjYWxsKENsaXBib2FyZFNldFRleHQsIHt0ZXh0fSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgdGhlIENsaXBib2FyZCB0ZXh0XHJcbiAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZz59XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gVGV4dCgpIHtcclxuICAgIHJldHVybiBjYWxsKENsaXBib2FyZFRleHQpO1xyXG59IiwgImxldCB1cmxBbHBoYWJldCA9XG4gICd1c2VhbmRvbS0yNlQxOTgzNDBQWDc1cHhKQUNLVkVSWU1JTkRCVVNIV09MRl9HUVpiZmdoamtscXZ3eXpyaWN0J1xuZXhwb3J0IGxldCBjdXN0b21BbHBoYWJldCA9IChhbHBoYWJldCwgZGVmYXVsdFNpemUgPSAyMSkgPT4ge1xuICByZXR1cm4gKHNpemUgPSBkZWZhdWx0U2l6ZSkgPT4ge1xuICAgIGxldCBpZCA9ICcnXG4gICAgbGV0IGkgPSBzaXplXG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgaWQgKz0gYWxwaGFiZXRbKE1hdGgucmFuZG9tKCkgKiBhbHBoYWJldC5sZW5ndGgpIHwgMF1cbiAgICB9XG4gICAgcmV0dXJuIGlkXG4gIH1cbn1cbmV4cG9ydCBsZXQgbmFub2lkID0gKHNpemUgPSAyMSkgPT4ge1xuICBsZXQgaWQgPSAnJ1xuICBsZXQgaSA9IHNpemVcbiAgd2hpbGUgKGktLSkge1xuICAgIGlkICs9IHVybEFscGhhYmV0WyhNYXRoLnJhbmRvbSgpICogNjQpIHwgMF1cbiAgfVxuICByZXR1cm4gaWRcbn1cbiIsICIvKlxyXG4gXyAgICAgX18gICAgIF8gX19cclxufCB8ICAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcbmltcG9ydCB7IG5hbm9pZCB9IGZyb20gJ25hbm9pZC9ub24tc2VjdXJlJztcclxuXHJcbmNvbnN0IHJ1bnRpbWVVUkwgPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luICsgXCIvd2FpbHMvcnVudGltZVwiO1xyXG4vLyBPYmplY3QgTmFtZXNcclxuZXhwb3J0IGNvbnN0IG9iamVjdE5hbWVzID0ge1xyXG4gICAgQ2FsbDogMCxcclxuICAgIENsaXBib2FyZDogMSxcclxuICAgIEFwcGxpY2F0aW9uOiAyLFxyXG4gICAgRXZlbnRzOiAzLFxyXG4gICAgQ29udGV4dE1lbnU6IDQsXHJcbiAgICBEaWFsb2c6IDUsXHJcbiAgICBXaW5kb3c6IDYsXHJcbiAgICBTY3JlZW5zOiA3LFxyXG4gICAgU3lzdGVtOiA4LFxyXG4gICAgQnJvd3NlcjogOSxcclxufVxyXG5leHBvcnQgbGV0IGNsaWVudElkID0gbmFub2lkKCk7XHJcblxyXG5mdW5jdGlvbiBydW50aW1lQ2FsbChtZXRob2QsIHdpbmRvd05hbWUsIGFyZ3MpIHtcclxuICAgIGxldCB1cmwgPSBuZXcgVVJMKHJ1bnRpbWVVUkwpO1xyXG4gICAgaWYoIG1ldGhvZCApIHtcclxuICAgICAgICB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChcIm1ldGhvZFwiLCBtZXRob2QpO1xyXG4gICAgfVxyXG4gICAgbGV0IGZldGNoT3B0aW9ucyA9IHtcclxuICAgICAgICBoZWFkZXJzOiB7fSxcclxuICAgIH07XHJcbiAgICBpZiAod2luZG93TmFtZSkge1xyXG4gICAgICAgIGZldGNoT3B0aW9ucy5oZWFkZXJzW1wieC13YWlscy13aW5kb3ctbmFtZVwiXSA9IHdpbmRvd05hbWU7XHJcbiAgICB9XHJcbiAgICBpZiAoYXJncykge1xyXG4gICAgICAgIHVybC5zZWFyY2hQYXJhbXMuYXBwZW5kKFwiYXJnc1wiLCBKU09OLnN0cmluZ2lmeShhcmdzKSk7XHJcbiAgICB9XHJcbiAgICBmZXRjaE9wdGlvbnMuaGVhZGVyc1tcIngtd2FpbHMtY2xpZW50LWlkXCJdID0gY2xpZW50SWQ7XHJcblxyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICBmZXRjaCh1cmwsIGZldGNoT3B0aW9ucylcclxuICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgY29udGVudCB0eXBlXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiQ29udGVudC1UeXBlXCIpICYmIHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiQ29udGVudC1UeXBlXCIpLmluZGV4T2YoXCJhcHBsaWNhdGlvbi9qc29uXCIpICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZS50ZXh0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKHJlc3BvbnNlLnN0YXR1c1RleHQpKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLnRoZW4oZGF0YSA9PiByZXNvbHZlKGRhdGEpKVxyXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIG5ld1J1bnRpbWVDYWxsZXIob2JqZWN0LCB3aW5kb3dOYW1lKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKG1ldGhvZCwgYXJncz1udWxsKSB7XHJcbiAgICAgICAgcmV0dXJuIHJ1bnRpbWVDYWxsKG9iamVjdCArIFwiLlwiICsgbWV0aG9kLCB3aW5kb3dOYW1lLCBhcmdzKTtcclxuICAgIH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJ1bnRpbWVDYWxsV2l0aElEKG9iamVjdElELCBtZXRob2QsIHdpbmRvd05hbWUsIGFyZ3MpIHtcclxuICAgIGxldCB1cmwgPSBuZXcgVVJMKHJ1bnRpbWVVUkwpO1xyXG4gICAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoXCJvYmplY3RcIiwgb2JqZWN0SUQpO1xyXG4gICAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoXCJtZXRob2RcIiwgbWV0aG9kKTtcclxuICAgIGxldCBmZXRjaE9wdGlvbnMgPSB7XHJcbiAgICAgICAgaGVhZGVyczoge30sXHJcbiAgICB9O1xyXG4gICAgaWYgKHdpbmRvd05hbWUpIHtcclxuICAgICAgICBmZXRjaE9wdGlvbnMuaGVhZGVyc1tcIngtd2FpbHMtd2luZG93LW5hbWVcIl0gPSB3aW5kb3dOYW1lO1xyXG4gICAgfVxyXG4gICAgaWYgKGFyZ3MpIHtcclxuICAgICAgICB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChcImFyZ3NcIiwgSlNPTi5zdHJpbmdpZnkoYXJncykpO1xyXG4gICAgfVxyXG4gICAgZmV0Y2hPcHRpb25zLmhlYWRlcnNbXCJ4LXdhaWxzLWNsaWVudC1pZFwiXSA9IGNsaWVudElkO1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICBmZXRjaCh1cmwsIGZldGNoT3B0aW9ucylcclxuICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgY29udGVudCB0eXBlXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiQ29udGVudC1UeXBlXCIpICYmIHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiQ29udGVudC1UeXBlXCIpLmluZGV4T2YoXCJhcHBsaWNhdGlvbi9qc29uXCIpICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZS50ZXh0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKHJlc3BvbnNlLnN0YXR1c1RleHQpKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLnRoZW4oZGF0YSA9PiByZXNvbHZlKGRhdGEpKVxyXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIG5ld1J1bnRpbWVDYWxsZXJXaXRoSUQob2JqZWN0LCB3aW5kb3dOYW1lKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKG1ldGhvZCwgYXJncz1udWxsKSB7XHJcbiAgICAgICAgcmV0dXJuIHJ1bnRpbWVDYWxsV2l0aElEKG9iamVjdCwgbWV0aG9kLCB3aW5kb3dOYW1lLCBhcmdzKTtcclxuICAgIH07XHJcbn1cclxuIiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmxldCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5BcHBsaWNhdGlvbik7XHJcblxyXG5sZXQgbWV0aG9kcyA9IHtcclxuICAgIEhpZGU6IDAsXHJcbiAgICBTaG93OiAxLFxyXG4gICAgUXVpdDogMixcclxufVxyXG5cclxuLyoqXHJcbiAqIEhpZGUgdGhlIGFwcGxpY2F0aW9uXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gSGlkZSgpIHtcclxuICAgIHZvaWQgY2FsbChtZXRob2RzLkhpZGUpO1xyXG59XHJcblxyXG4vKipcclxuICogU2hvdyB0aGUgYXBwbGljYXRpb25cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBTaG93KCkge1xyXG4gICAgdm9pZCBjYWxsKG1ldGhvZHMuU2hvdyk7XHJcbn1cclxuXHJcblxyXG4vKipcclxuICogUXVpdCB0aGUgYXBwbGljYXRpb25cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBRdWl0KCkge1xyXG4gICAgdm9pZCBjYWxsKG1ldGhvZHMuUXVpdCk7XHJcbn0iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuLyoganNoaW50IGVzdmVyc2lvbjogOSAqL1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL2FwaS90eXBlc1wiKS5TY3JlZW59IFNjcmVlblxyXG4gKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmxldCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5TY3JlZW5zKTtcclxuXHJcbmxldCBTY3JlZW5zR2V0QWxsID0gMDtcclxubGV0IFNjcmVlbnNHZXRQcmltYXJ5ID0gMTtcclxubGV0IFNjcmVlbnNHZXRDdXJyZW50ID0gMjtcclxuXHJcbi8qKlxyXG4gKiBHZXRzIGFsbCBzY3JlZW5zLlxyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxTY3JlZW5bXT59XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gR2V0QWxsKCkge1xyXG4gICAgcmV0dXJuIGNhbGwoU2NyZWVuc0dldEFsbCk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBwcmltYXJ5IHNjcmVlbi5cclxuICogQHJldHVybnMge1Byb21pc2U8U2NyZWVuPn1cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBHZXRQcmltYXJ5KCkge1xyXG4gICAgcmV0dXJuIGNhbGwoU2NyZWVuc0dldFByaW1hcnkpO1xyXG59XHJcblxyXG4vKipcclxuICogR2V0cyB0aGUgY3VycmVudCBhY3RpdmUgc2NyZWVuLlxyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxTY3JlZW4+fVxyXG4gKiBAY29uc3RydWN0b3JcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBHZXRDdXJyZW50KCkge1xyXG4gICAgcmV0dXJuIGNhbGwoU2NyZWVuc0dldEN1cnJlbnQpO1xyXG59IiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmxldCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5TeXN0ZW0pO1xyXG5cclxubGV0IFN5c3RlbUlzRGFya01vZGUgPSAwO1xyXG5cclxuLyoqXHJcbiAqIERldGVybWluZXMgaWYgdGhlIHN5c3RlbSBpcyBjdXJyZW50bHkgdXNpbmcgZGFyayBtb2RlXHJcbiAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIElzRGFya01vZGUoKSB7XHJcbiAgICByZXR1cm4gY2FsbChTeXN0ZW1Jc0RhcmtNb2RlKTtcclxufSIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcblxyXG5pbXBvcnQge25ld1J1bnRpbWVDYWxsZXJXaXRoSUQsIG9iamVjdE5hbWVzfSBmcm9tIFwiLi9ydW50aW1lXCI7XHJcblxyXG5sZXQgY2FsbCA9IG5ld1J1bnRpbWVDYWxsZXJXaXRoSUQob2JqZWN0TmFtZXMuQnJvd3Nlcik7XHJcblxyXG5sZXQgQnJvd3Nlck9wZW5VUkwgPSAwO1xyXG5cclxuLyoqXHJcbiAqIE9wZW4gYSBicm93c2VyIHdpbmRvdyB0byB0aGUgZ2l2ZW4gVVJMXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgLSBUaGUgVVJMIHRvIG9wZW5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBPcGVuVVJMKHVybCkge1xyXG4gICAgdm9pZCBjYWxsKEJyb3dzZXJPcGVuVVJMLCB7dXJsfSk7XHJcbn1cclxuIiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmltcG9ydCB7IG5hbm9pZCB9IGZyb20gJ25hbm9pZC9ub24tc2VjdXJlJztcclxuXHJcbmxldCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5DYWxsKTtcclxuXHJcbmxldCBDYWxsQmluZGluZyA9IDA7XHJcblxyXG5sZXQgY2FsbFJlc3BvbnNlcyA9IG5ldyBNYXAoKTtcclxuXHJcbmZ1bmN0aW9uIGdlbmVyYXRlSUQoKSB7XHJcbiAgICBsZXQgcmVzdWx0O1xyXG4gICAgZG8ge1xyXG4gICAgICAgIHJlc3VsdCA9IG5hbm9pZCgpO1xyXG4gICAgfSB3aGlsZSAoY2FsbFJlc3BvbnNlcy5oYXMocmVzdWx0KSk7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY2FsbENhbGxiYWNrKGlkLCBkYXRhLCBpc0pTT04pIHtcclxuICAgIGxldCBwID0gY2FsbFJlc3BvbnNlcy5nZXQoaWQpO1xyXG4gICAgaWYgKHApIHtcclxuICAgICAgICBpZiAoaXNKU09OKSB7XHJcbiAgICAgICAgICAgIHAucmVzb2x2ZShKU09OLnBhcnNlKGRhdGEpKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBwLnJlc29sdmUoZGF0YSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhbGxSZXNwb25zZXMuZGVsZXRlKGlkKTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGNhbGxFcnJvckNhbGxiYWNrKGlkLCBtZXNzYWdlKSB7XHJcbiAgICBsZXQgcCA9IGNhbGxSZXNwb25zZXMuZ2V0KGlkKTtcclxuICAgIGlmIChwKSB7XHJcbiAgICAgICAgcC5yZWplY3QobWVzc2FnZSk7XHJcbiAgICAgICAgY2FsbFJlc3BvbnNlcy5kZWxldGUoaWQpO1xyXG4gICAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBjYWxsQmluZGluZyh0eXBlLCBvcHRpb25zKSB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgIGxldCBpZCA9IGdlbmVyYXRlSUQoKTtcclxuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcclxuICAgICAgICBvcHRpb25zW1wiY2FsbC1pZFwiXSA9IGlkO1xyXG5cclxuICAgICAgICBjYWxsUmVzcG9uc2VzLnNldChpZCwge3Jlc29sdmUsIHJlamVjdH0pO1xyXG4gICAgICAgIGNhbGwodHlwZSwgb3B0aW9ucykuY2F0Y2goKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAgIHJlamVjdChlcnJvcik7XHJcbiAgICAgICAgICAgIGNhbGxSZXNwb25zZXMuZGVsZXRlKGlkKTtcclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gQ2FsbChvcHRpb25zKSB7XHJcbiAgICByZXR1cm4gY2FsbEJpbmRpbmcoQ2FsbEJpbmRpbmcsIG9wdGlvbnMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gQ2FsbEJ5TmFtZShuYW1lLCAuLi5hcmdzKSB7XHJcblxyXG4gICAgLy8gRW5zdXJlIGZpcnN0IGFyZ3VtZW50IGlzIGEgc3RyaW5nIGFuZCBoYXMgMiBkb3RzXHJcbiAgICBpZiAodHlwZW9mIG5hbWUgIT09IFwic3RyaW5nXCIgfHwgbmFtZS5zcGxpdChcIi5cIikubGVuZ3RoICE9PSAzKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FsbEJ5TmFtZSByZXF1aXJlcyBhIHN0cmluZyBpbiB0aGUgZm9ybWF0ICdwYWNrYWdlLnN0cnVjdC5tZXRob2QnXCIpO1xyXG4gICAgfVxyXG4gICAgLy8gU3BsaXQgaW5wdXRzXHJcbiAgICBsZXQgcGFydHMgPSBuYW1lLnNwbGl0KFwiLlwiKTtcclxuXHJcbiAgICByZXR1cm4gY2FsbEJpbmRpbmcoQ2FsbEJpbmRpbmcsIHtcclxuICAgICAgICBwYWNrYWdlTmFtZTogcGFydHNbMF0sXHJcbiAgICAgICAgc3RydWN0TmFtZTogcGFydHNbMV0sXHJcbiAgICAgICAgbWV0aG9kTmFtZTogcGFydHNbMl0sXHJcbiAgICAgICAgYXJnczogYXJncyxcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gQ2FsbEJ5SUQobWV0aG9kSUQsIC4uLmFyZ3MpIHtcclxuICAgIHJldHVybiBjYWxsQmluZGluZyhDYWxsQmluZGluZywge1xyXG4gICAgICAgIG1ldGhvZElEOiBtZXRob2RJRCxcclxuICAgICAgICBhcmdzOiBhcmdzLFxyXG4gICAgfSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDYWxsIGEgcGx1Z2luIG1ldGhvZFxyXG4gKiBAcGFyYW0ge3N0cmluZ30gcGx1Z2luTmFtZSAtIG5hbWUgb2YgdGhlIHBsdWdpblxyXG4gKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kTmFtZSAtIG5hbWUgb2YgdGhlIG1ldGhvZFxyXG4gKiBAcGFyYW0gey4uLmFueX0gYXJncyAtIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBtZXRob2RcclxuICogQHJldHVybnMge1Byb21pc2U8YW55Pn0gLSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgcmVzdWx0XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gUGx1Z2luKHBsdWdpbk5hbWUsIG1ldGhvZE5hbWUsIC4uLmFyZ3MpIHtcclxuICAgIHJldHVybiBjYWxsQmluZGluZyhDYWxsQmluZGluZywge1xyXG4gICAgICAgIHBhY2thZ2VOYW1lOiBcIndhaWxzLXBsdWdpbnNcIixcclxuICAgICAgICBzdHJ1Y3ROYW1lOiBwbHVnaW5OYW1lLFxyXG4gICAgICAgIG1ldGhvZE5hbWU6IG1ldGhvZE5hbWUsXHJcbiAgICAgICAgYXJnczogYXJncyxcclxuICAgIH0pO1xyXG59IiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbi8qKlxyXG4gKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi4vYXBpL3R5cGVzXCIpLlNpemV9IFNpemVcclxuICogQHR5cGVkZWYge2ltcG9ydChcIi4uL2FwaS90eXBlc1wiKS5Qb3NpdGlvbn0gUG9zaXRpb25cclxuICogQHR5cGVkZWYge2ltcG9ydChcIi4uL2FwaS90eXBlc1wiKS5TY3JlZW59IFNjcmVlblxyXG4gKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmxldCBXaW5kb3dDZW50ZXIgPSAwO1xyXG5sZXQgV2luZG93U2V0VGl0bGUgPSAxO1xyXG5sZXQgV2luZG93RnVsbHNjcmVlbiA9IDI7XHJcbmxldCBXaW5kb3dVbkZ1bGxzY3JlZW4gPSAzO1xyXG5sZXQgV2luZG93U2V0U2l6ZSA9IDQ7XHJcbmxldCBXaW5kb3dTaXplID0gNTtcclxubGV0IFdpbmRvd1NldE1heFNpemUgPSA2O1xyXG5sZXQgV2luZG93U2V0TWluU2l6ZSA9IDc7XHJcbmxldCBXaW5kb3dTZXRBbHdheXNPblRvcCA9IDg7XHJcbmxldCBXaW5kb3dTZXRSZWxhdGl2ZVBvc2l0aW9uID0gOTtcclxubGV0IFdpbmRvd1JlbGF0aXZlUG9zaXRpb24gPSAxMDtcclxubGV0IFdpbmRvd1NjcmVlbiA9IDExO1xyXG5sZXQgV2luZG93SGlkZSA9IDEyO1xyXG5sZXQgV2luZG93TWF4aW1pc2UgPSAxMztcclxubGV0IFdpbmRvd1VuTWF4aW1pc2UgPSAxNDtcclxubGV0IFdpbmRvd1RvZ2dsZU1heGltaXNlID0gMTU7XHJcbmxldCBXaW5kb3dNaW5pbWlzZSA9IDE2O1xyXG5sZXQgV2luZG93VW5NaW5pbWlzZSA9IDE3O1xyXG5sZXQgV2luZG93UmVzdG9yZSA9IDE4O1xyXG5sZXQgV2luZG93U2hvdyA9IDE5O1xyXG5sZXQgV2luZG93Q2xvc2UgPSAyMDtcclxubGV0IFdpbmRvd1NldEJhY2tncm91bmRDb2xvdXIgPSAyMTtcclxubGV0IFdpbmRvd1NldFJlc2l6YWJsZSA9IDIyO1xyXG5sZXQgV2luZG93V2lkdGggPSAyMztcclxubGV0IFdpbmRvd0hlaWdodCA9IDI0O1xyXG5sZXQgV2luZG93Wm9vbUluID0gMjU7XHJcbmxldCBXaW5kb3dab29tT3V0ID0gMjY7XHJcbmxldCBXaW5kb3dab29tUmVzZXQgPSAyNztcclxubGV0IFdpbmRvd0dldFpvb21MZXZlbCA9IDI4O1xyXG5sZXQgV2luZG93U2V0Wm9vbUxldmVsID0gMjk7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbmV3V2luZG93KHdpbmRvd05hbWUpIHtcclxuICAgIGxldCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5XaW5kb3csIHdpbmRvd05hbWUpO1xyXG4gICAgcmV0dXJuIHtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ2VudGVycyB0aGUgd2luZG93LlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIENlbnRlcjogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd0NlbnRlciksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFNldCB0aGUgd2luZG93IHRpdGxlLlxyXG4gICAgICAgICAqIEBwYXJhbSB0aXRsZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFNldFRpdGxlOiAodGl0bGUpID0+IHZvaWQgY2FsbChXaW5kb3dTZXRUaXRsZSwge3RpdGxlfSksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIE1ha2VzIHRoZSB3aW5kb3cgZnVsbHNjcmVlbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICBGdWxsc2NyZWVuOiAoKSA9PiB2b2lkIGNhbGwoV2luZG93RnVsbHNjcmVlbiksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFVuZnVsbHNjcmVlbiB0aGUgd2luZG93LlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFVuRnVsbHNjcmVlbjogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd1VuRnVsbHNjcmVlbiksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFNldCB0aGUgd2luZG93IHNpemUuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoIFRoZSB3aW5kb3cgd2lkdGhcclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IFRoZSB3aW5kb3cgaGVpZ2h0XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgU2V0U2l6ZTogKHdpZHRoLCBoZWlnaHQpID0+IGNhbGwoV2luZG93U2V0U2l6ZSwge3dpZHRoLGhlaWdodH0pLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXQgdGhlIHdpbmRvdyBzaXplLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtQcm9taXNlPFNpemU+fSBUaGUgd2luZG93IHNpemVcclxuICAgICAgICAgKi9cclxuICAgICAgICBTaXplOiAoKSA9PiB7IHJldHVybiBjYWxsKFdpbmRvd1NpemUpOyB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgdGhlIHdpbmRvdyBtYXhpbXVtIHNpemUuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFNldE1heFNpemU6ICh3aWR0aCwgaGVpZ2h0KSA9PiB2b2lkIGNhbGwoV2luZG93U2V0TWF4U2l6ZSwge3dpZHRoLGhlaWdodH0pLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgdGhlIHdpbmRvdyBtaW5pbXVtIHNpemUuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFNldE1pblNpemU6ICh3aWR0aCwgaGVpZ2h0KSA9PiB2b2lkIGNhbGwoV2luZG93U2V0TWluU2l6ZSwge3dpZHRoLGhlaWdodH0pLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgd2luZG93IHRvIGJlIGFsd2F5cyBvbiB0b3AuXHJcbiAgICAgICAgICogQHBhcmFtIHtib29sZWFufSBvblRvcCBXaGV0aGVyIHRoZSB3aW5kb3cgc2hvdWxkIGJlIGFsd2F5cyBvbiB0b3BcclxuICAgICAgICAgKi9cclxuICAgICAgICBTZXRBbHdheXNPblRvcDogKG9uVG9wKSA9PiB2b2lkIGNhbGwoV2luZG93U2V0QWx3YXlzT25Ub3AsIHthbHdheXNPblRvcDpvblRvcH0pLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgdGhlIHdpbmRvdyByZWxhdGl2ZSBwb3NpdGlvbi5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0geFxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgU2V0UmVsYXRpdmVQb3NpdGlvbjogKHgsIHkpID0+IGNhbGwoV2luZG93U2V0UmVsYXRpdmVQb3NpdGlvbiwge3gseX0pLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXQgdGhlIHdpbmRvdyBwb3NpdGlvbi5cclxuICAgICAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxQb3NpdGlvbj59IFRoZSB3aW5kb3cgcG9zaXRpb25cclxuICAgICAgICAgKi9cclxuICAgICAgICBSZWxhdGl2ZVBvc2l0aW9uOiAoKSA9PiB7IHJldHVybiBjYWxsKFdpbmRvd1JlbGF0aXZlUG9zaXRpb24pOyB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXQgdGhlIHNjcmVlbiB0aGUgd2luZG93IGlzIG9uLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtQcm9taXNlPFNjcmVlbj59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgU2NyZWVuOiAoKSA9PiB7IHJldHVybiBjYWxsKFdpbmRvd1NjcmVlbik7IH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEhpZGUgdGhlIHdpbmRvd1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEhpZGU6ICgpID0+IHZvaWQgY2FsbChXaW5kb3dIaWRlKSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogTWF4aW1pc2UgdGhlIHdpbmRvd1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIE1heGltaXNlOiAoKSA9PiB2b2lkIGNhbGwoV2luZG93TWF4aW1pc2UpLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTaG93IHRoZSB3aW5kb3dcclxuICAgICAgICAgKi9cclxuICAgICAgICBTaG93OiAoKSA9PiB2b2lkIGNhbGwoV2luZG93U2hvdyksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENsb3NlIHRoZSB3aW5kb3dcclxuICAgICAgICAgKi9cclxuICAgICAgICBDbG9zZTogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd0Nsb3NlKSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVG9nZ2xlIHRoZSB3aW5kb3cgbWF4aW1pc2Ugc3RhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBUb2dnbGVNYXhpbWlzZTogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd1RvZ2dsZU1heGltaXNlKSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVW5tYXhpbWlzZSB0aGUgd2luZG93XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgVW5NYXhpbWlzZTogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd1VuTWF4aW1pc2UpLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBNaW5pbWlzZSB0aGUgd2luZG93XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgTWluaW1pc2U6ICgpID0+IHZvaWQgY2FsbChXaW5kb3dNaW5pbWlzZSksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFVubWluaW1pc2UgdGhlIHdpbmRvd1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFVuTWluaW1pc2U6ICgpID0+IHZvaWQgY2FsbChXaW5kb3dVbk1pbmltaXNlKSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmVzdG9yZSB0aGUgd2luZG93XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgUmVzdG9yZTogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd1Jlc3RvcmUpLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgdGhlIGJhY2tncm91bmQgY29sb3VyIG9mIHRoZSB3aW5kb3cuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHIgLSBBIHZhbHVlIGJldHdlZW4gMCBhbmQgMjU1XHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGcgLSBBIHZhbHVlIGJldHdlZW4gMCBhbmQgMjU1XHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGIgLSBBIHZhbHVlIGJldHdlZW4gMCBhbmQgMjU1XHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGEgLSBBIHZhbHVlIGJldHdlZW4gMCBhbmQgMjU1XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgU2V0QmFja2dyb3VuZENvbG91cjogKHIsIGcsIGIsIGEpID0+IHZvaWQgY2FsbChXaW5kb3dTZXRCYWNrZ3JvdW5kQ29sb3VyLCB7ciwgZywgYiwgYX0pLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgd2hldGhlciB0aGUgd2luZG93IGNhbiBiZSByZXNpemVkIG9yIG5vdFxyXG4gICAgICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gcmVzaXphYmxlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgU2V0UmVzaXphYmxlOiAocmVzaXphYmxlKSA9PiB2b2lkIGNhbGwoV2luZG93U2V0UmVzaXphYmxlLCB7cmVzaXphYmxlfSksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEdldCB0aGUgd2luZG93IHdpZHRoXHJcbiAgICAgICAgICogQHJldHVybnMge1Byb21pc2U8bnVtYmVyPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBXaWR0aDogKCkgPT4geyByZXR1cm4gY2FsbChXaW5kb3dXaWR0aCk7IH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEdldCB0aGUgd2luZG93IGhlaWdodFxyXG4gICAgICAgICAqIEByZXR1cm5zIHtQcm9taXNlPG51bWJlcj59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgSGVpZ2h0OiAoKSA9PiB7IHJldHVybiBjYWxsKFdpbmRvd0hlaWdodCk7IH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFpvb20gaW4gdGhlIHdpbmRvd1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFpvb21JbjogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd1pvb21JbiksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFpvb20gb3V0IHRoZSB3aW5kb3dcclxuICAgICAgICAgKi9cclxuICAgICAgICBab29tT3V0OiAoKSA9PiB2b2lkIGNhbGwoV2luZG93Wm9vbU91dCksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJlc2V0IHRoZSB3aW5kb3cgem9vbVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFpvb21SZXNldDogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd1pvb21SZXNldCksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEdldCB0aGUgd2luZG93IHpvb21cclxuICAgICAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxudW1iZXI+fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEdldFpvb21MZXZlbDogKCkgPT4geyByZXR1cm4gY2FsbChXaW5kb3dHZXRab29tTGV2ZWwpOyB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgdGhlIHdpbmRvdyB6b29tIGxldmVsXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHpvb21MZXZlbFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFNldFpvb21MZXZlbDogKHpvb21MZXZlbCkgPT4gdm9pZCBjYWxsKFdpbmRvd1NldFpvb21MZXZlbCwge3pvb21MZXZlbH0pLFxyXG4gICAgfTtcclxufVxyXG4iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuLyoganNoaW50IGVzdmVyc2lvbjogOSAqL1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL2FwaS90eXBlc1wiKS5XYWlsc0V2ZW50fSBXYWlsc0V2ZW50XHJcbiAqL1xyXG5cclxuaW1wb3J0IHtuZXdSdW50aW1lQ2FsbGVyV2l0aElELCBvYmplY3ROYW1lc30gZnJvbSBcIi4vcnVudGltZVwiO1xyXG5cclxubGV0IGNhbGwgPSBuZXdSdW50aW1lQ2FsbGVyV2l0aElEKG9iamVjdE5hbWVzLkV2ZW50cyk7XHJcbmxldCBFdmVudEVtaXQgPSAwO1xyXG5cclxuLyoqXHJcbiAqIFRoZSBMaXN0ZW5lciBjbGFzcyBkZWZpbmVzIGEgbGlzdGVuZXIhIDotKVxyXG4gKlxyXG4gKiBAY2xhc3MgTGlzdGVuZXJcclxuICovXHJcbmNsYXNzIExpc3RlbmVyIHtcclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBMaXN0ZW5lci5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWVcclxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWF4Q2FsbGJhY2tzXHJcbiAgICAgKiBAbWVtYmVyb2YgTGlzdGVuZXJcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IoZXZlbnROYW1lLCBjYWxsYmFjaywgbWF4Q2FsbGJhY2tzKSB7XHJcbiAgICAgICAgdGhpcy5ldmVudE5hbWUgPSBldmVudE5hbWU7XHJcbiAgICAgICAgLy8gRGVmYXVsdCBvZiAtMSBtZWFucyBpbmZpbml0ZVxyXG4gICAgICAgIHRoaXMubWF4Q2FsbGJhY2tzID0gbWF4Q2FsbGJhY2tzIHx8IC0xO1xyXG4gICAgICAgIC8vIENhbGxiYWNrIGludm9rZXMgdGhlIGNhbGxiYWNrIHdpdGggdGhlIGdpdmVuIGRhdGFcclxuICAgICAgICAvLyBSZXR1cm5zIHRydWUgaWYgdGhpcyBsaXN0ZW5lciBzaG91bGQgYmUgZGVzdHJveWVkXHJcbiAgICAgICAgdGhpcy5DYWxsYmFjayA9IChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgIGNhbGxiYWNrKGRhdGEpO1xyXG4gICAgICAgICAgICAvLyBJZiBtYXhDYWxsYmFja3MgaXMgaW5maW5pdGUsIHJldHVybiBmYWxzZSAoZG8gbm90IGRlc3Ryb3kpXHJcbiAgICAgICAgICAgIGlmICh0aGlzLm1heENhbGxiYWNrcyA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBEZWNyZW1lbnQgbWF4Q2FsbGJhY2tzLiBSZXR1cm4gdHJ1ZSBpZiBub3cgMCwgb3RoZXJ3aXNlIGZhbHNlXHJcbiAgICAgICAgICAgIHRoaXMubWF4Q2FsbGJhY2tzIC09IDE7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1heENhbGxiYWNrcyA9PT0gMDtcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIFdhaWxzRXZlbnQgZGVmaW5lcyBhIGN1c3RvbSBldmVudC4gSXQgaXMgcGFzc2VkIHRvIGV2ZW50IGxpc3RlbmVycy5cclxuICpcclxuICogQGNsYXNzIFdhaWxzRXZlbnRcclxuICogQHByb3BlcnR5IHtzdHJpbmd9IG5hbWUgLSBOYW1lIG9mIHRoZSBldmVudFxyXG4gKiBAcHJvcGVydHkge2FueX0gZGF0YSAtIERhdGEgYXNzb2NpYXRlZCB3aXRoIHRoZSBldmVudFxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIFdhaWxzRXZlbnQge1xyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIFdhaWxzRXZlbnQuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIE5hbWUgb2YgdGhlIGV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge2FueT1udWxsfSBkYXRhIC0gRGF0YSBhc3NvY2lhdGVkIHdpdGggdGhlIGV2ZW50XHJcbiAgICAgKiBAbWVtYmVyb2YgV2FpbHNFdmVudFxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcihuYW1lLCBkYXRhID0gbnVsbCkge1xyXG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XHJcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IGV2ZW50TGlzdGVuZXJzID0gbmV3IE1hcCgpO1xyXG5cclxuLyoqXHJcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBgbWF4Q2FsbGJhY2tzYCB0aW1lcyBiZWZvcmUgYmVpbmcgZGVzdHJveWVkXHJcbiAqXHJcbiAqIEBleHBvcnRcclxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxyXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFdhaWxzRXZlbnQpOiB2b2lkfSBjYWxsYmFja1xyXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4Q2FsbGJhY2tzXHJcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gQSBmdW5jdGlvbiB0byBjYW5jZWwgdGhlIGxpc3RlbmVyXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gT25NdWx0aXBsZShldmVudE5hbWUsIGNhbGxiYWNrLCBtYXhDYWxsYmFja3MpIHtcclxuICAgIGxldCBsaXN0ZW5lcnMgPSBldmVudExpc3RlbmVycy5nZXQoZXZlbnROYW1lKSB8fCBbXTtcclxuICAgIGNvbnN0IHRoaXNMaXN0ZW5lciA9IG5ldyBMaXN0ZW5lcihldmVudE5hbWUsIGNhbGxiYWNrLCBtYXhDYWxsYmFja3MpO1xyXG4gICAgbGlzdGVuZXJzLnB1c2godGhpc0xpc3RlbmVyKTtcclxuICAgIGV2ZW50TGlzdGVuZXJzLnNldChldmVudE5hbWUsIGxpc3RlbmVycyk7XHJcbiAgICByZXR1cm4gKCkgPT4gbGlzdGVuZXJPZmYodGhpc0xpc3RlbmVyKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBldmVyeSB0aW1lIHRoZSBldmVudCBpcyBlbWl0dGVkXHJcbiAqXHJcbiAqIEBleHBvcnRcclxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxyXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFdhaWxzRXZlbnQpOiB2b2lkfSBjYWxsYmFja1xyXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IEEgZnVuY3Rpb24gdG8gY2FuY2VsIHRoZSBsaXN0ZW5lclxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIE9uKGV2ZW50TmFtZSwgY2FsbGJhY2spIHtcclxuICAgIHJldHVybiBPbk11bHRpcGxlKGV2ZW50TmFtZSwgY2FsbGJhY2ssIC0xKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBvbmNlIHRoZW4gZGVzdHJveWVkXHJcbiAqXHJcbiAqIEBleHBvcnRcclxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxyXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFdhaWxzRXZlbnQpOiB2b2lkfSBjYWxsYmFja1xyXG4gQHJldHVybnMge2Z1bmN0aW9ufSBBIGZ1bmN0aW9uIHRvIGNhbmNlbCB0aGUgbGlzdGVuZXJcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBPbmNlKGV2ZW50TmFtZSwgY2FsbGJhY2spIHtcclxuICAgIHJldHVybiBPbk11bHRpcGxlKGV2ZW50TmFtZSwgY2FsbGJhY2ssIDEpO1xyXG59XHJcblxyXG4vKipcclxuICogbGlzdGVuZXJPZmYgdW5yZWdpc3RlcnMgYSBsaXN0ZW5lciBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgd2l0aCBPblxyXG4gKlxyXG4gKiBAcGFyYW0ge0xpc3RlbmVyfSBsaXN0ZW5lclxyXG4gKi9cclxuZnVuY3Rpb24gbGlzdGVuZXJPZmYobGlzdGVuZXIpIHtcclxuICAgIGNvbnN0IGV2ZW50TmFtZSA9IGxpc3RlbmVyLmV2ZW50TmFtZTtcclxuICAgIC8vIFJlbW92ZSBsb2NhbCBsaXN0ZW5lclxyXG4gICAgbGV0IGxpc3RlbmVycyA9IGV2ZW50TGlzdGVuZXJzLmdldChldmVudE5hbWUpLmZpbHRlcihsID0+IGwgIT09IGxpc3RlbmVyKTtcclxuICAgIGlmIChsaXN0ZW5lcnMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgZXZlbnRMaXN0ZW5lcnMuZGVsZXRlKGV2ZW50TmFtZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIGV2ZW50TGlzdGVuZXJzLnNldChldmVudE5hbWUsIGxpc3RlbmVycyk7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBkaXNwYXRjaGVzIGFuIGV2ZW50IHRvIGFsbCBsaXN0ZW5lcnNcclxuICpcclxuICogQGV4cG9ydFxyXG4gKiBAcGFyYW0ge1dhaWxzRXZlbnR9IGV2ZW50XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZGlzcGF0Y2hXYWlsc0V2ZW50KGV2ZW50KSB7XHJcbiAgICBsZXQgbGlzdGVuZXJzID0gZXZlbnRMaXN0ZW5lcnMuZ2V0KGV2ZW50Lm5hbWUpO1xyXG4gICAgaWYgKGxpc3RlbmVycykge1xyXG4gICAgICAgIC8vIGl0ZXJhdGUgbGlzdGVuZXJzIGFuZCBjYWxsIGNhbGxiYWNrLiBJZiBjYWxsYmFjayByZXR1cm5zIHRydWUsIHJlbW92ZSBsaXN0ZW5lclxyXG4gICAgICAgIGxldCB0b1JlbW92ZSA9IFtdO1xyXG4gICAgICAgIGxpc3RlbmVycy5mb3JFYWNoKGxpc3RlbmVyID0+IHtcclxuICAgICAgICAgICAgbGV0IHJlbW92ZSA9IGxpc3RlbmVyLkNhbGxiYWNrKGV2ZW50KTtcclxuICAgICAgICAgICAgaWYgKHJlbW92ZSkge1xyXG4gICAgICAgICAgICAgICAgdG9SZW1vdmUucHVzaChsaXN0ZW5lcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyByZW1vdmUgbGlzdGVuZXJzXHJcbiAgICAgICAgaWYgKHRvUmVtb3ZlLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgbGlzdGVuZXJzID0gbGlzdGVuZXJzLmZpbHRlcihsID0+ICF0b1JlbW92ZS5pbmNsdWRlcyhsKSk7XHJcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBldmVudExpc3RlbmVycy5kZWxldGUoZXZlbnQubmFtZSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBldmVudExpc3RlbmVycy5zZXQoZXZlbnQubmFtZSwgbGlzdGVuZXJzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIE9mZiB1bnJlZ2lzdGVycyBhIGxpc3RlbmVyIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCB3aXRoIE9uLFxyXG4gKiBvcHRpb25hbGx5IG11bHRpcGxlIGxpc3RlbmVycyBjYW4gYmUgdW5yZWdpc3RlcmVkIHZpYSBgYWRkaXRpb25hbEV2ZW50TmFtZXNgXHJcbiAqXHJcbiBbdjMgQ0hBTkdFXSBPZmYgb25seSB1bnJlZ2lzdGVycyBsaXN0ZW5lcnMgd2l0aGluIHRoZSBjdXJyZW50IHdpbmRvd1xyXG4gKlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lXHJcbiAqIEBwYXJhbSAgey4uLnN0cmluZ30gYWRkaXRpb25hbEV2ZW50TmFtZXNcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBPZmYoZXZlbnROYW1lLCAuLi5hZGRpdGlvbmFsRXZlbnROYW1lcykge1xyXG4gICAgbGV0IGV2ZW50c1RvUmVtb3ZlID0gW2V2ZW50TmFtZSwgLi4uYWRkaXRpb25hbEV2ZW50TmFtZXNdO1xyXG4gICAgZXZlbnRzVG9SZW1vdmUuZm9yRWFjaChldmVudE5hbWUgPT4ge1xyXG4gICAgICAgIGV2ZW50TGlzdGVuZXJzLmRlbGV0ZShldmVudE5hbWUpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBPZmZBbGwgdW5yZWdpc3RlcnMgYWxsIGxpc3RlbmVyc1xyXG4gKiBbdjMgQ0hBTkdFXSBPZmZBbGwgb25seSB1bnJlZ2lzdGVycyBsaXN0ZW5lcnMgd2l0aGluIHRoZSBjdXJyZW50IHdpbmRvd1xyXG4gKlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIE9mZkFsbCgpIHtcclxuICAgIGV2ZW50TGlzdGVuZXJzLmNsZWFyKCk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBFbWl0IGFuIGV2ZW50XHJcbiAqIEBwYXJhbSB7V2FpbHNFdmVudH0gZXZlbnQgVGhlIGV2ZW50IHRvIGVtaXRcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBFbWl0KGV2ZW50KSB7XHJcbiAgICB2b2lkIGNhbGwoRXZlbnRFbWl0LCBldmVudCk7XHJcbn0iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuLyoganNoaW50IGVzdmVyc2lvbjogOSAqL1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL2FwaS90eXBlc1wiKS5NZXNzYWdlRGlhbG9nT3B0aW9uc30gTWVzc2FnZURpYWxvZ09wdGlvbnNcclxuICogQHR5cGVkZWYge2ltcG9ydChcIi4vYXBpL3R5cGVzXCIpLk9wZW5EaWFsb2dPcHRpb25zfSBPcGVuRGlhbG9nT3B0aW9uc1xyXG4gKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi9hcGkvdHlwZXNcIikuU2F2ZURpYWxvZ09wdGlvbnN9IFNhdmVEaWFsb2dPcHRpb25zXHJcbiAqL1xyXG5cclxuaW1wb3J0IHtuZXdSdW50aW1lQ2FsbGVyV2l0aElELCBvYmplY3ROYW1lc30gZnJvbSBcIi4vcnVudGltZVwiO1xyXG5cclxuaW1wb3J0IHsgbmFub2lkIH0gZnJvbSAnbmFub2lkL25vbi1zZWN1cmUnO1xyXG5cclxubGV0IGNhbGwgPSBuZXdSdW50aW1lQ2FsbGVyV2l0aElEKG9iamVjdE5hbWVzLkRpYWxvZyk7XHJcblxyXG5sZXQgRGlhbG9nSW5mbyA9IDA7XHJcbmxldCBEaWFsb2dXYXJuaW5nID0gMTtcclxubGV0IERpYWxvZ0Vycm9yID0gMjtcclxubGV0IERpYWxvZ1F1ZXN0aW9uID0gMztcclxubGV0IERpYWxvZ09wZW5GaWxlID0gNDtcclxubGV0IERpYWxvZ1NhdmVGaWxlID0gNTtcclxuXHJcblxyXG5sZXQgZGlhbG9nUmVzcG9uc2VzID0gbmV3IE1hcCgpO1xyXG5cclxuZnVuY3Rpb24gZ2VuZXJhdGVJRCgpIHtcclxuICAgIGxldCByZXN1bHQ7XHJcbiAgICBkbyB7XHJcbiAgICAgICAgcmVzdWx0ID0gbmFub2lkKCk7XHJcbiAgICB9IHdoaWxlIChkaWFsb2dSZXNwb25zZXMuaGFzKHJlc3VsdCkpO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGRpYWxvZ0NhbGxiYWNrKGlkLCBkYXRhLCBpc0pTT04pIHtcclxuICAgIGxldCBwID0gZGlhbG9nUmVzcG9uc2VzLmdldChpZCk7XHJcbiAgICBpZiAocCkge1xyXG4gICAgICAgIGlmIChpc0pTT04pIHtcclxuICAgICAgICAgICAgcC5yZXNvbHZlKEpTT04ucGFyc2UoZGF0YSkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHAucmVzb2x2ZShkYXRhKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZGlhbG9nUmVzcG9uc2VzLmRlbGV0ZShpZCk7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0IGZ1bmN0aW9uIGRpYWxvZ0Vycm9yQ2FsbGJhY2soaWQsIG1lc3NhZ2UpIHtcclxuICAgIGxldCBwID0gZGlhbG9nUmVzcG9uc2VzLmdldChpZCk7XHJcbiAgICBpZiAocCkge1xyXG4gICAgICAgIHAucmVqZWN0KG1lc3NhZ2UpO1xyXG4gICAgICAgIGRpYWxvZ1Jlc3BvbnNlcy5kZWxldGUoaWQpO1xyXG4gICAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBkaWFsb2codHlwZSwgb3B0aW9ucykge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICBsZXQgaWQgPSBnZW5lcmF0ZUlEKCk7XHJcbiAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcbiAgICAgICAgb3B0aW9uc1tcImRpYWxvZy1pZFwiXSA9IGlkO1xyXG4gICAgICAgIGRpYWxvZ1Jlc3BvbnNlcy5zZXQoaWQsIHtyZXNvbHZlLCByZWplY3R9KTtcclxuICAgICAgICBjYWxsKHR5cGUsIG9wdGlvbnMpLmNhdGNoKChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgICByZWplY3QoZXJyb3IpO1xyXG4gICAgICAgICAgICBkaWFsb2dSZXNwb25zZXMuZGVsZXRlKGlkKTtcclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIFNob3dzIGFuIEluZm8gZGlhbG9nIHdpdGggdGhlIGdpdmVuIG9wdGlvbnMuXHJcbiAqIEBwYXJhbSB7TWVzc2FnZURpYWxvZ09wdGlvbnN9IG9wdGlvbnNcclxuICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nPn0gVGhlIGxhYmVsIG9mIHRoZSBidXR0b24gcHJlc3NlZFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIEluZm8ob3B0aW9ucykge1xyXG4gICAgcmV0dXJuIGRpYWxvZyhEaWFsb2dJbmZvLCBvcHRpb25zKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFNob3dzIGEgV2FybmluZyBkaWFsb2cgd2l0aCB0aGUgZ2l2ZW4gb3B0aW9ucy5cclxuICogQHBhcmFtIHtNZXNzYWdlRGlhbG9nT3B0aW9uc30gb3B0aW9uc1xyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fSBUaGUgbGFiZWwgb2YgdGhlIGJ1dHRvbiBwcmVzc2VkXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gV2FybmluZyhvcHRpb25zKSB7XHJcbiAgICByZXR1cm4gZGlhbG9nKERpYWxvZ1dhcm5pbmcsIG9wdGlvbnMpO1xyXG59XHJcblxyXG4vKipcclxuICogU2hvd3MgYW4gRXJyb3IgZGlhbG9nIHdpdGggdGhlIGdpdmVuIG9wdGlvbnMuXHJcbiAqIEBwYXJhbSB7TWVzc2FnZURpYWxvZ09wdGlvbnN9IG9wdGlvbnNcclxuICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nPn0gVGhlIGxhYmVsIG9mIHRoZSBidXR0b24gcHJlc3NlZFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIEVycm9yKG9wdGlvbnMpIHtcclxuICAgIHJldHVybiBkaWFsb2coRGlhbG9nRXJyb3IsIG9wdGlvbnMpO1xyXG59XHJcblxyXG4vKipcclxuICogU2hvd3MgYSBRdWVzdGlvbiBkaWFsb2cgd2l0aCB0aGUgZ2l2ZW4gb3B0aW9ucy5cclxuICogQHBhcmFtIHtNZXNzYWdlRGlhbG9nT3B0aW9uc30gb3B0aW9uc1xyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fSBUaGUgbGFiZWwgb2YgdGhlIGJ1dHRvbiBwcmVzc2VkXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gUXVlc3Rpb24ob3B0aW9ucykge1xyXG4gICAgcmV0dXJuIGRpYWxvZyhEaWFsb2dRdWVzdGlvbiwgb3B0aW9ucyk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBTaG93cyBhbiBPcGVuIGRpYWxvZyB3aXRoIHRoZSBnaXZlbiBvcHRpb25zLlxyXG4gKiBAcGFyYW0ge09wZW5EaWFsb2dPcHRpb25zfSBvcHRpb25zXHJcbiAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZ1tdfHN0cmluZz59IFJldHVybnMgdGhlIHNlbGVjdGVkIGZpbGUgb3IgYW4gYXJyYXkgb2Ygc2VsZWN0ZWQgZmlsZXMgaWYgQWxsb3dzTXVsdGlwbGVTZWxlY3Rpb24gaXMgdHJ1ZS4gQSBibGFuayBzdHJpbmcgaXMgcmV0dXJuZWQgaWYgbm8gZmlsZSB3YXMgc2VsZWN0ZWQuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gT3BlbkZpbGUob3B0aW9ucykge1xyXG4gICAgcmV0dXJuIGRpYWxvZyhEaWFsb2dPcGVuRmlsZSwgb3B0aW9ucyk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBTaG93cyBhIFNhdmUgZGlhbG9nIHdpdGggdGhlIGdpdmVuIG9wdGlvbnMuXHJcbiAqIEBwYXJhbSB7U2F2ZURpYWxvZ09wdGlvbnN9IG9wdGlvbnNcclxuICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nPn0gUmV0dXJucyB0aGUgc2VsZWN0ZWQgZmlsZS4gQSBibGFuayBzdHJpbmcgaXMgcmV0dXJuZWQgaWYgbm8gZmlsZSB3YXMgc2VsZWN0ZWQuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gU2F2ZUZpbGUob3B0aW9ucykge1xyXG4gICAgcmV0dXJuIGRpYWxvZyhEaWFsb2dTYXZlRmlsZSwgb3B0aW9ucyk7XHJcbn1cclxuXHJcbiIsICJpbXBvcnQge25ld1J1bnRpbWVDYWxsZXJXaXRoSUQsIG9iamVjdE5hbWVzfSBmcm9tIFwiLi9ydW50aW1lXCI7XHJcblxyXG5sZXQgY2FsbCA9IG5ld1J1bnRpbWVDYWxsZXJXaXRoSUQob2JqZWN0TmFtZXMuQ29udGV4dE1lbnUpO1xyXG5cclxubGV0IENvbnRleHRNZW51T3BlbiA9IDA7XHJcblxyXG5mdW5jdGlvbiBvcGVuQ29udGV4dE1lbnUoaWQsIHgsIHksIGRhdGEpIHtcclxuICAgIHZvaWQgY2FsbChDb250ZXh0TWVudU9wZW4sIHtpZCwgeCwgeSwgZGF0YX0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gc2V0dXBDb250ZXh0TWVudXMoKSB7XHJcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignY29udGV4dG1lbnUnLCBjb250ZXh0TWVudUhhbmRsZXIpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjb250ZXh0TWVudUhhbmRsZXIoZXZlbnQpIHtcclxuICAgIC8vIENoZWNrIGZvciBjdXN0b20gY29udGV4dCBtZW51XHJcbiAgICBsZXQgZWxlbWVudCA9IGV2ZW50LnRhcmdldDtcclxuICAgIGxldCBjdXN0b21Db250ZXh0TWVudSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpLmdldFByb3BlcnR5VmFsdWUoXCItLWN1c3RvbS1jb250ZXh0bWVudVwiKTtcclxuICAgIGN1c3RvbUNvbnRleHRNZW51ID0gY3VzdG9tQ29udGV4dE1lbnUgPyBjdXN0b21Db250ZXh0TWVudS50cmltKCkgOiBcIlwiO1xyXG4gICAgaWYgKGN1c3RvbUNvbnRleHRNZW51KSB7XHJcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICBsZXQgY3VzdG9tQ29udGV4dE1lbnVEYXRhID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWxlbWVudCkuZ2V0UHJvcGVydHlWYWx1ZShcIi0tY3VzdG9tLWNvbnRleHRtZW51LWRhdGFcIik7XHJcbiAgICAgICAgb3BlbkNvbnRleHRNZW51KGN1c3RvbUNvbnRleHRNZW51LCBldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCBjdXN0b21Db250ZXh0TWVudURhdGEpO1xyXG4gICAgICAgIHJldHVyblxyXG4gICAgfVxyXG5cclxuICAgIHByb2Nlc3NEZWZhdWx0Q29udGV4dE1lbnUoZXZlbnQpO1xyXG59XHJcblxyXG5cclxuLypcclxuLS1kZWZhdWx0LWNvbnRleHRtZW51OiBhdXRvOyAoZGVmYXVsdCkgd2lsbCBzaG93IHRoZSBkZWZhdWx0IGNvbnRleHQgbWVudSBpZiBjb250ZW50RWRpdGFibGUgaXMgdHJ1ZSBPUiB0ZXh0IGhhcyBiZWVuIHNlbGVjdGVkIE9SIGVsZW1lbnQgaXMgaW5wdXQgb3IgdGV4dGFyZWFcclxuLS1kZWZhdWx0LWNvbnRleHRtZW51OiBzaG93OyB3aWxsIGFsd2F5cyBzaG93IHRoZSBkZWZhdWx0IGNvbnRleHQgbWVudVxyXG4tLWRlZmF1bHQtY29udGV4dG1lbnU6IGhpZGU7IHdpbGwgYWx3YXlzIGhpZGUgdGhlIGRlZmF1bHQgY29udGV4dCBtZW51XHJcblxyXG5UaGlzIHJ1bGUgaXMgaW5oZXJpdGVkIGxpa2Ugbm9ybWFsIENTUyBydWxlcywgc28gbmVzdGluZyB3b3JrcyBhcyBleHBlY3RlZFxyXG4qL1xyXG5mdW5jdGlvbiBwcm9jZXNzRGVmYXVsdENvbnRleHRNZW51KGV2ZW50KSB7XHJcbiAgICAvLyBEZWJ1ZyBidWlsZHMgYWx3YXlzIHNob3cgdGhlIG1lbnVcclxuICAgIGlmIChERUJVRykge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBQcm9jZXNzIGRlZmF1bHQgY29udGV4dCBtZW51XHJcbiAgICBjb25zdCBlbGVtZW50ID0gZXZlbnQudGFyZ2V0O1xyXG4gICAgY29uc3QgY29tcHV0ZWRTdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xyXG4gICAgY29uc3QgZGVmYXVsdENvbnRleHRNZW51QWN0aW9uID0gY29tcHV0ZWRTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKFwiLS1kZWZhdWx0LWNvbnRleHRtZW51XCIpLnRyaW0oKTtcclxuICAgIHN3aXRjaCAoZGVmYXVsdENvbnRleHRNZW51QWN0aW9uKSB7XHJcbiAgICAgICAgY2FzZSBcInNob3dcIjpcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIGNhc2UgXCJoaWRlXCI6XHJcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAvLyBDaGVjayBpZiBjb250ZW50RWRpdGFibGUgaXMgdHJ1ZVxyXG4gICAgICAgICAgICBpZiAoZWxlbWVudC5pc0NvbnRlbnRFZGl0YWJsZSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBDaGVjayBpZiB0ZXh0IGhhcyBiZWVuIHNlbGVjdGVkXHJcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcclxuICAgICAgICAgICAgY29uc3QgaGFzU2VsZWN0aW9uID0gKHNlbGVjdGlvbi50b1N0cmluZygpLmxlbmd0aCA+IDApXHJcbiAgICAgICAgICAgIGlmIChoYXNTZWxlY3Rpb24pIHtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZWN0aW9uLnJhbmdlQ291bnQ7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoaSk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVjdHMgPSByYW5nZS5nZXRDbGllbnRSZWN0cygpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgcmVjdHMubGVuZ3RoOyBqKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVjdCA9IHJlY3RzW2pdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChyZWN0LmxlZnQsIHJlY3QudG9wKSA9PT0gZWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHRhZ25hbWUgaXMgaW5wdXQgb3IgdGV4dGFyZWFcclxuICAgICAgICAgICAgaWYgKGVsZW1lbnQudGFnTmFtZSA9PT0gXCJJTlBVVFwiIHx8IGVsZW1lbnQudGFnTmFtZSA9PT0gXCJURVhUQVJFQVwiKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaGFzU2VsZWN0aW9uIHx8ICghZWxlbWVudC5yZWFkT25seSAmJiAhZWxlbWVudC5kaXNhYmxlZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGhpZGUgZGVmYXVsdCBjb250ZXh0IG1lbnVcclxuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgIH1cclxufVxyXG4iLCAiXHJcbmltcG9ydCB7RW1pdCwgV2FpbHNFdmVudH0gZnJvbSBcIi4vZXZlbnRzXCI7XHJcbmltcG9ydCB7UXVlc3Rpb259IGZyb20gXCIuL2RpYWxvZ3NcIjtcclxuXHJcbmZ1bmN0aW9uIHNlbmRFdmVudChldmVudE5hbWUsIGRhdGE9bnVsbCkge1xyXG4gICAgbGV0IGV2ZW50ID0gbmV3IFdhaWxzRXZlbnQoZXZlbnROYW1lLCBkYXRhKTtcclxuICAgIEVtaXQoZXZlbnQpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRXTUxFdmVudExpc3RlbmVycygpIHtcclxuICAgIGNvbnN0IGVsZW1lbnRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW3dtbC1ldmVudF0nKTtcclxuICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICBjb25zdCBldmVudFR5cGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLWV2ZW50Jyk7XHJcbiAgICAgICAgY29uc3QgY29uZmlybSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd3bWwtY29uZmlybScpO1xyXG4gICAgICAgIGNvbnN0IHRyaWdnZXIgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLXRyaWdnZXInKSB8fCBcImNsaWNrXCI7XHJcblxyXG4gICAgICAgIGxldCBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKGNvbmZpcm0pIHtcclxuICAgICAgICAgICAgICAgIFF1ZXN0aW9uKHtUaXRsZTogXCJDb25maXJtXCIsIE1lc3NhZ2U6Y29uZmlybSwgRGV0YWNoZWQ6IGZhbHNlLCBCdXR0b25zOlt7TGFiZWw6XCJZZXNcIn0se0xhYmVsOlwiTm9cIiwgSXNEZWZhdWx0OnRydWV9XX0pLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT09IFwiTm9cIikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZW5kRXZlbnQoZXZlbnRUeXBlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBzZW5kRXZlbnQoZXZlbnRUeXBlKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vIFJlbW92ZSBleGlzdGluZyBsaXN0ZW5lcnNcclxuXHJcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKHRyaWdnZXIsIGNhbGxiYWNrKTtcclxuXHJcbiAgICAgICAgLy8gQWRkIG5ldyBsaXN0ZW5lclxyXG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcih0cmlnZ2VyLCBjYWxsYmFjayk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gY2FsbFdpbmRvd01ldGhvZChtZXRob2QpIHtcclxuICAgIGlmICh3YWlscy5XaW5kb3dbbWV0aG9kXSA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgY29uc29sZS5sb2coXCJXaW5kb3cgbWV0aG9kIFwiICsgbWV0aG9kICsgXCIgbm90IGZvdW5kXCIpO1xyXG4gICAgfVxyXG4gICAgd2FpbHMuV2luZG93W21ldGhvZF0oKTtcclxufVxyXG5cclxuZnVuY3Rpb24gYWRkV01MV2luZG93TGlzdGVuZXJzKCkge1xyXG4gICAgY29uc3QgZWxlbWVudHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdbd21sLXdpbmRvd10nKTtcclxuICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICBjb25zdCB3aW5kb3dNZXRob2QgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLXdpbmRvdycpO1xyXG4gICAgICAgIGNvbnN0IGNvbmZpcm0gPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLWNvbmZpcm0nKTtcclxuICAgICAgICBjb25zdCB0cmlnZ2VyID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3dtbC10cmlnZ2VyJykgfHwgXCJjbGlja1wiO1xyXG5cclxuICAgICAgICBsZXQgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChjb25maXJtKSB7XHJcbiAgICAgICAgICAgICAgICBRdWVzdGlvbih7VGl0bGU6IFwiQ29uZmlybVwiLCBNZXNzYWdlOmNvbmZpcm0sIEJ1dHRvbnM6W3tMYWJlbDpcIlllc1wifSx7TGFiZWw6XCJOb1wiLCBJc0RlZmF1bHQ6dHJ1ZX1dfSkudGhlbihmdW5jdGlvbiAocmVzdWx0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPT0gXCJOb1wiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxXaW5kb3dNZXRob2Qod2luZG93TWV0aG9kKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYWxsV2luZG93TWV0aG9kKHdpbmRvd01ldGhvZCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLy8gUmVtb3ZlIGV4aXN0aW5nIGxpc3RlbmVyc1xyXG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcih0cmlnZ2VyLCBjYWxsYmFjayk7XHJcblxyXG4gICAgICAgIC8vIEFkZCBuZXcgbGlzdGVuZXJcclxuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIodHJpZ2dlciwgY2FsbGJhY2spO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGFkZFdNTE9wZW5Ccm93c2VyTGlzdGVuZXIoKSB7XHJcbiAgICBjb25zdCBlbGVtZW50cyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ1t3bWwtb3BlbnVybF0nKTtcclxuICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICBjb25zdCB1cmwgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLW9wZW51cmwnKTtcclxuICAgICAgICBjb25zdCBjb25maXJtID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3dtbC1jb25maXJtJyk7XHJcbiAgICAgICAgY29uc3QgdHJpZ2dlciA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd3bWwtdHJpZ2dlcicpIHx8IFwiY2xpY2tcIjtcclxuXHJcbiAgICAgICAgbGV0IGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAoY29uZmlybSkge1xyXG4gICAgICAgICAgICAgICAgUXVlc3Rpb24oe1RpdGxlOiBcIkNvbmZpcm1cIiwgTWVzc2FnZTpjb25maXJtLCBCdXR0b25zOlt7TGFiZWw6XCJZZXNcIn0se0xhYmVsOlwiTm9cIiwgSXNEZWZhdWx0OnRydWV9XX0pLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT09IFwiTm9cIikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2b2lkIHdhaWxzLkJyb3dzZXIuT3BlblVSTCh1cmwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZvaWQgd2FpbHMuQnJvd3Nlci5PcGVuVVJMKHVybCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLy8gUmVtb3ZlIGV4aXN0aW5nIGxpc3RlbmVyc1xyXG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcih0cmlnZ2VyLCBjYWxsYmFjayk7XHJcblxyXG4gICAgICAgIC8vIEFkZCBuZXcgbGlzdGVuZXJcclxuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIodHJpZ2dlciwgY2FsbGJhY2spO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiByZWxvYWRXTUwoKSB7XHJcbiAgICBhZGRXTUxFdmVudExpc3RlbmVycygpO1xyXG4gICAgYWRkV01MV2luZG93TGlzdGVuZXJzKCk7XHJcbiAgICBhZGRXTUxPcGVuQnJvd3Nlckxpc3RlbmVyKCk7XHJcbn1cclxuIiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbi8vIGRlZmluZWQgaW4gdGhlIFRhc2tmaWxlXHJcbmV4cG9ydCBsZXQgaW52b2tlID0gZnVuY3Rpb24oaW5wdXQpIHtcclxuICAgIGlmKFdJTkRPV1MpIHtcclxuICAgICAgICBjaHJvbWUud2Vidmlldy5wb3N0TWVzc2FnZShpbnB1dCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIHdlYmtpdC5tZXNzYWdlSGFuZGxlcnMuZXh0ZXJuYWwucG9zdE1lc3NhZ2UoaW5wdXQpO1xyXG4gICAgfVxyXG59XHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcblxyXG5sZXQgZmxhZ3MgPSBuZXcgTWFwKCk7XHJcblxyXG5mdW5jdGlvbiBjb252ZXJ0VG9NYXAob2JqKSB7XHJcbiAgICBjb25zdCBtYXAgPSBuZXcgTWFwKCk7XHJcblxyXG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMob2JqKSkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIG1hcC5zZXQoa2V5LCBjb252ZXJ0VG9NYXAodmFsdWUpKTsgLy8gUmVjdXJzaXZlbHkgY29udmVydCBuZXN0ZWQgb2JqZWN0XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgbWFwLnNldChrZXksIHZhbHVlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG1hcDtcclxufVxyXG5cclxuZmV0Y2goXCIvd2FpbHMvZmxhZ3NcIikudGhlbigocmVzcG9uc2UpID0+IHtcclxuICAgIHJlc3BvbnNlLmpzb24oKS50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgICAgZmxhZ3MgPSBjb252ZXJ0VG9NYXAoZGF0YSk7XHJcbiAgICB9KTtcclxufSk7XHJcblxyXG5cclxuZnVuY3Rpb24gZ2V0VmFsdWVGcm9tTWFwKGtleVN0cmluZykge1xyXG4gICAgY29uc3Qga2V5cyA9IGtleVN0cmluZy5zcGxpdCgnLicpO1xyXG4gICAgbGV0IHZhbHVlID0gZmxhZ3M7XHJcblxyXG4gICAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xyXG4gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIE1hcCkge1xyXG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLmdldChrZXkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHZhbHVlID0gdmFsdWVba2V5XTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdmFsdWU7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBHZXRGbGFnKGtleVN0cmluZykge1xyXG4gICAgcmV0dXJuIGdldFZhbHVlRnJvbU1hcChrZXlTdHJpbmcpO1xyXG59XHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcblxyXG5pbXBvcnQge2ludm9rZX0gZnJvbSBcIi4vaW52b2tlXCI7XHJcbmltcG9ydCB7R2V0RmxhZ30gZnJvbSBcIi4vZmxhZ3NcIjtcclxuXHJcbmxldCBzaG91bGREcmFnID0gZmFsc2U7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZHJhZ1Rlc3QoZSkge1xyXG4gICAgbGV0IHZhbCA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGUudGFyZ2V0KS5nZXRQcm9wZXJ0eVZhbHVlKFwiLS13ZWJraXQtYXBwLXJlZ2lvblwiKTtcclxuICAgIGlmICh2YWwpIHtcclxuICAgICAgICB2YWwgPSB2YWwudHJpbSgpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh2YWwgIT09IFwiZHJhZ1wiKSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIE9ubHkgcHJvY2VzcyB0aGUgcHJpbWFyeSBidXR0b25cclxuICAgIGlmIChlLmJ1dHRvbnMgIT09IDEpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGUuZGV0YWlsID09PSAxO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gc2V0dXBEcmFnKCkge1xyXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIG9uTW91c2VEb3duKTtcclxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBvbk1vdXNlTW92ZSk7XHJcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIG9uTW91c2VVcCk7XHJcbn1cclxuXHJcbmxldCByZXNpemVFZGdlID0gbnVsbDtcclxubGV0IHJlc2l6YWJsZSA9IGZhbHNlO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHNldFJlc2l6YWJsZSh2YWx1ZSkge1xyXG4gICAgcmVzaXphYmxlID0gdmFsdWU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHRlc3RSZXNpemUoZSkge1xyXG4gICAgaWYoIHJlc2l6ZUVkZ2UgKSB7XHJcbiAgICAgICAgaW52b2tlKFwicmVzaXplOlwiICsgcmVzaXplRWRnZSk7XHJcbiAgICAgICAgcmV0dXJuIHRydWVcclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZTtcclxufVxyXG5cclxuZnVuY3Rpb24gb25Nb3VzZURvd24oZSkge1xyXG5cclxuICAgIC8vIENoZWNrIGZvciByZXNpemluZyBvbiBXaW5kb3dzXHJcbiAgICBpZiggV0lORE9XUyApIHtcclxuICAgICAgICBpZiAodGVzdFJlc2l6ZSgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAoZHJhZ1Rlc3QoZSkpIHtcclxuICAgICAgICAvLyBJZ25vcmUgZHJhZyBvbiBzY3JvbGxiYXJzXHJcbiAgICAgICAgaWYgKGUub2Zmc2V0WCA+IGUudGFyZ2V0LmNsaWVudFdpZHRoIHx8IGUub2Zmc2V0WSA+IGUudGFyZ2V0LmNsaWVudEhlaWdodCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHNob3VsZERyYWcgPSB0cnVlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICBzaG91bGREcmFnID0gZmFsc2U7XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIG9uTW91c2VVcChlKSB7XHJcbiAgICBsZXQgbW91c2VQcmVzc2VkID0gZS5idXR0b25zICE9PSB1bmRlZmluZWQgPyBlLmJ1dHRvbnMgOiBlLndoaWNoO1xyXG4gICAgaWYgKG1vdXNlUHJlc3NlZCA+IDApIHtcclxuICAgICAgICBlbmREcmFnKCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBlbmREcmFnKCkge1xyXG4gICAgZG9jdW1lbnQuYm9keS5zdHlsZS5jdXJzb3IgPSAnZGVmYXVsdCc7XHJcbiAgICBzaG91bGREcmFnID0gZmFsc2U7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNldFJlc2l6ZShjdXJzb3IpIHtcclxuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5jdXJzb3IgPSBjdXJzb3IgfHwgZGVmYXVsdEN1cnNvcjtcclxuICAgIHJlc2l6ZUVkZ2UgPSBjdXJzb3I7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIG9uTW91c2VNb3ZlKGUpIHtcclxuICAgIGlmIChzaG91bGREcmFnKSB7XHJcbiAgICAgICAgc2hvdWxkRHJhZyA9IGZhbHNlO1xyXG4gICAgICAgIGxldCBtb3VzZVByZXNzZWQgPSBlLmJ1dHRvbnMgIT09IHVuZGVmaW5lZCA/IGUuYnV0dG9ucyA6IGUud2hpY2g7XHJcbiAgICAgICAgaWYgKG1vdXNlUHJlc3NlZCA+IDApIHtcclxuICAgICAgICAgICAgaW52b2tlKFwiZHJhZ1wiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChXSU5ET1dTKSB7XHJcbiAgICAgICAgaWYgKHJlc2l6YWJsZSkge1xyXG4gICAgICAgICAgICBoYW5kbGVSZXNpemUoZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG5sZXQgZGVmYXVsdEN1cnNvciA9IFwiYXV0b1wiO1xyXG5cclxuZnVuY3Rpb24gaGFuZGxlUmVzaXplKGUpIHtcclxuICAgIGxldCByZXNpemVIYW5kbGVIZWlnaHQgPSBHZXRGbGFnKFwic3lzdGVtLnJlc2l6ZUhhbmRsZUhlaWdodFwiKSB8fCA1O1xyXG4gICAgbGV0IHJlc2l6ZUhhbmRsZVdpZHRoID0gR2V0RmxhZyhcInN5c3RlbS5yZXNpemVIYW5kbGVXaWR0aFwiKSB8fCA1O1xyXG5cclxuICAgIC8vIEV4dHJhIHBpeGVscyBmb3IgdGhlIGNvcm5lciBhcmVhc1xyXG4gICAgbGV0IGNvcm5lckV4dHJhID0gR2V0RmxhZyhcInJlc2l6ZUNvcm5lckV4dHJhXCIpIHx8IDEwO1xyXG5cclxuICAgIGxldCByaWdodEJvcmRlciA9IHdpbmRvdy5vdXRlcldpZHRoIC0gZS5jbGllbnRYIDwgcmVzaXplSGFuZGxlV2lkdGg7XHJcbiAgICBsZXQgbGVmdEJvcmRlciA9IGUuY2xpZW50WCA8IHJlc2l6ZUhhbmRsZVdpZHRoO1xyXG4gICAgbGV0IHRvcEJvcmRlciA9IGUuY2xpZW50WSA8IHJlc2l6ZUhhbmRsZUhlaWdodDtcclxuICAgIGxldCBib3R0b21Cb3JkZXIgPSB3aW5kb3cub3V0ZXJIZWlnaHQgLSBlLmNsaWVudFkgPCByZXNpemVIYW5kbGVIZWlnaHQ7XHJcblxyXG4gICAgLy8gQWRqdXN0IGZvciBjb3JuZXJzXHJcbiAgICBsZXQgcmlnaHRDb3JuZXIgPSB3aW5kb3cub3V0ZXJXaWR0aCAtIGUuY2xpZW50WCA8IChyZXNpemVIYW5kbGVXaWR0aCArIGNvcm5lckV4dHJhKTtcclxuICAgIGxldCBsZWZ0Q29ybmVyID0gZS5jbGllbnRYIDwgKHJlc2l6ZUhhbmRsZVdpZHRoICsgY29ybmVyRXh0cmEpO1xyXG4gICAgbGV0IHRvcENvcm5lciA9IGUuY2xpZW50WSA8IChyZXNpemVIYW5kbGVIZWlnaHQgKyBjb3JuZXJFeHRyYSk7XHJcbiAgICBsZXQgYm90dG9tQ29ybmVyID0gd2luZG93Lm91dGVySGVpZ2h0IC0gZS5jbGllbnRZIDwgKHJlc2l6ZUhhbmRsZUhlaWdodCArIGNvcm5lckV4dHJhKTtcclxuXHJcbiAgICAvLyBJZiB3ZSBhcmVuJ3Qgb24gYW4gZWRnZSwgYnV0IHdlcmUsIHJlc2V0IHRoZSBjdXJzb3IgdG8gZGVmYXVsdFxyXG4gICAgaWYgKCFsZWZ0Qm9yZGVyICYmICFyaWdodEJvcmRlciAmJiAhdG9wQm9yZGVyICYmICFib3R0b21Cb3JkZXIgJiYgcmVzaXplRWRnZSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgc2V0UmVzaXplKCk7XHJcbiAgICB9XHJcbiAgICAvLyBBZGp1c3RlZCBmb3IgY29ybmVyIGFyZWFzXHJcbiAgICBlbHNlIGlmIChyaWdodENvcm5lciAmJiBib3R0b21Db3JuZXIpIHNldFJlc2l6ZShcInNlLXJlc2l6ZVwiKTtcclxuICAgIGVsc2UgaWYgKGxlZnRDb3JuZXIgJiYgYm90dG9tQ29ybmVyKSBzZXRSZXNpemUoXCJzdy1yZXNpemVcIik7XHJcbiAgICBlbHNlIGlmIChsZWZ0Q29ybmVyICYmIHRvcENvcm5lcikgc2V0UmVzaXplKFwibnctcmVzaXplXCIpO1xyXG4gICAgZWxzZSBpZiAodG9wQ29ybmVyICYmIHJpZ2h0Q29ybmVyKSBzZXRSZXNpemUoXCJuZS1yZXNpemVcIik7XHJcbiAgICBlbHNlIGlmIChsZWZ0Qm9yZGVyKSBzZXRSZXNpemUoXCJ3LXJlc2l6ZVwiKTtcclxuICAgIGVsc2UgaWYgKHRvcEJvcmRlcikgc2V0UmVzaXplKFwibi1yZXNpemVcIik7XHJcbiAgICBlbHNlIGlmIChib3R0b21Cb3JkZXIpIHNldFJlc2l6ZShcInMtcmVzaXplXCIpO1xyXG4gICAgZWxzZSBpZiAocmlnaHRCb3JkZXIpIHNldFJlc2l6ZShcImUtcmVzaXplXCIpO1xyXG59XHJcbiIsICIvKlxyXG4gXyAgICAgX18gICAgIF8gX19cclxufCB8ICAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcblxyXG5pbXBvcnQgKiBhcyBDbGlwYm9hcmQgZnJvbSAnLi9jbGlwYm9hcmQnO1xyXG5pbXBvcnQgKiBhcyBBcHBsaWNhdGlvbiBmcm9tICcuL2FwcGxpY2F0aW9uJztcclxuaW1wb3J0ICogYXMgU2NyZWVucyBmcm9tICcuL3NjcmVlbnMnO1xyXG5pbXBvcnQgKiBhcyBTeXN0ZW0gZnJvbSAnLi9zeXN0ZW0nO1xyXG5pbXBvcnQgKiBhcyBCcm93c2VyIGZyb20gJy4vYnJvd3Nlcic7XHJcbmltcG9ydCB7UGx1Z2luLCBDYWxsLCBjYWxsRXJyb3JDYWxsYmFjaywgY2FsbENhbGxiYWNrLCBDYWxsQnlJRCwgQ2FsbEJ5TmFtZX0gZnJvbSBcIi4vY2FsbHNcIjtcclxuaW1wb3J0IHtjbGllbnRJZH0gZnJvbSAnLi9ydW50aW1lJztcclxuaW1wb3J0IHtuZXdXaW5kb3d9IGZyb20gXCIuL3dpbmRvd1wiO1xyXG5pbXBvcnQge2Rpc3BhdGNoV2FpbHNFdmVudCwgRW1pdCwgT2ZmLCBPZmZBbGwsIE9uLCBPbmNlLCBPbk11bHRpcGxlfSBmcm9tIFwiLi9ldmVudHNcIjtcclxuaW1wb3J0IHtkaWFsb2dDYWxsYmFjaywgZGlhbG9nRXJyb3JDYWxsYmFjaywgRXJyb3IsIEluZm8sIE9wZW5GaWxlLCBRdWVzdGlvbiwgU2F2ZUZpbGUsIFdhcm5pbmcsfSBmcm9tIFwiLi9kaWFsb2dzXCI7XHJcbmltcG9ydCB7c2V0dXBDb250ZXh0TWVudXN9IGZyb20gXCIuL2NvbnRleHRtZW51XCI7XHJcbmltcG9ydCB7cmVsb2FkV01MfSBmcm9tIFwiLi93bWxcIjtcclxuaW1wb3J0IHtzZXR1cERyYWcsIGVuZERyYWcsIHNldFJlc2l6YWJsZX0gZnJvbSBcIi4vZHJhZ1wiO1xyXG5cclxud2luZG93LndhaWxzID0ge1xyXG4gICAgLi4ubmV3UnVudGltZShudWxsKSxcclxuICAgIENhcGFiaWxpdGllczoge30sXHJcbiAgICBjbGllbnRJZDogY2xpZW50SWQsXHJcbn07XHJcblxyXG5mZXRjaChcIi93YWlscy9jYXBhYmlsaXRpZXNcIikudGhlbigocmVzcG9uc2UpID0+IHtcclxuICAgIHJlc3BvbnNlLmpzb24oKS50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgICAgd2luZG93LndhaWxzLkNhcGFiaWxpdGllcyA9IGRhdGE7XHJcbiAgICB9KTtcclxufSk7XHJcblxyXG4vLyBJbnRlcm5hbCB3YWlscyBlbmRwb2ludHNcclxud2luZG93Ll93YWlscyA9IHtcclxuICAgIGRpYWxvZ0NhbGxiYWNrLFxyXG4gICAgZGlhbG9nRXJyb3JDYWxsYmFjayxcclxuICAgIGRpc3BhdGNoV2FpbHNFdmVudCxcclxuICAgIGNhbGxDYWxsYmFjayxcclxuICAgIGNhbGxFcnJvckNhbGxiYWNrLFxyXG4gICAgZW5kRHJhZyxcclxuICAgIHNldFJlc2l6YWJsZSxcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBuZXdSdW50aW1lKHdpbmRvd05hbWUpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgQ2xpcGJvYXJkOiB7XHJcbiAgICAgICAgICAgIC4uLkNsaXBib2FyZFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgQXBwbGljYXRpb246IHtcclxuICAgICAgICAgICAgLi4uQXBwbGljYXRpb24sXHJcbiAgICAgICAgICAgIEdldFdpbmRvd0J5TmFtZSh3aW5kb3dOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3UnVudGltZSh3aW5kb3dOYW1lKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgU3lzdGVtLFxyXG4gICAgICAgIFNjcmVlbnMsXHJcbiAgICAgICAgQnJvd3NlcixcclxuICAgICAgICBDYWxsLFxyXG4gICAgICAgIENhbGxCeUlELFxyXG4gICAgICAgIENhbGxCeU5hbWUsXHJcbiAgICAgICAgUGx1Z2luLFxyXG4gICAgICAgIFdNTDoge1xyXG4gICAgICAgICAgICBSZWxvYWQ6IHJlbG9hZFdNTCxcclxuICAgICAgICB9LFxyXG4gICAgICAgIERpYWxvZzoge1xyXG4gICAgICAgICAgICBJbmZvLFxyXG4gICAgICAgICAgICBXYXJuaW5nLFxyXG4gICAgICAgICAgICBFcnJvcixcclxuICAgICAgICAgICAgUXVlc3Rpb24sXHJcbiAgICAgICAgICAgIE9wZW5GaWxlLFxyXG4gICAgICAgICAgICBTYXZlRmlsZSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIEV2ZW50czoge1xyXG4gICAgICAgICAgICBFbWl0LFxyXG4gICAgICAgICAgICBPbixcclxuICAgICAgICAgICAgT25jZSxcclxuICAgICAgICAgICAgT25NdWx0aXBsZSxcclxuICAgICAgICAgICAgT2ZmLFxyXG4gICAgICAgICAgICBPZmZBbGwsXHJcbiAgICAgICAgfSxcclxuICAgICAgICBXaW5kb3c6IG5ld1dpbmRvdyh3aW5kb3dOYW1lKSxcclxuICAgIH07XHJcbn1cclxuXHJcbmlmIChERUJVRykge1xyXG4gICAgY29uc29sZS5sb2coXCJXYWlscyB2My4wLjAgRGVidWcgTW9kZSBFbmFibGVkXCIpO1xyXG59XHJcblxyXG5zZXR1cENvbnRleHRNZW51cygpO1xyXG5zZXR1cERyYWcoKTtcclxuXHJcbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGZ1bmN0aW9uKCkge1xyXG4gICAg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QSxJQUNoQyxDQUFDO0FBQUEsRUFDTCxDQUFDO0FBR0QsU0FBTyxTQUFTO0FBQUEsSUFDWjtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLEVBQ0o7QUFFTyxXQUFTLFdBQVcsWUFBWTtBQUNuQyxXQUFPO0FBQUEsTUFDSCxXQUFXO0FBQUEsUUFDUCxHQUFHO0FBQUEsTUFDUDtBQUFBLE1BQ0EsYUFBYTtBQUFBLFFBQ1QsR0FBRztBQUFBLFFBQ0gsZ0JBQWdCQyxhQUFZO0FBQ3hCLGlCQUFPLFdBQVdBLFdBQVU7QUFBQSxRQUNoQztBQUFBLE1BQ0o7QUFBQSxNQUNBO0FBQUEsTUFDQTtBQUFBLE1BQ0E7QUFBQSxNQUNBO0FBQUEsTUFDQTtBQUFBLE1BQ0E7QUFBQSxNQUNBO0FBQUEsTUFDQSxLQUFLO0FBQUEsUUFDRCxRQUFRO0FBQUEsTUFDWjtBQUFBLE1BQ0EsUUFBUTtBQUFBLFFBQ0o7QUFBQSxRQUNBO0FBQUEsUUFDQSxPQUFBQztBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLE1BQ0o7QUFBQSxNQUNBLFFBQVE7QUFBQSxRQUNKO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxNQUNKO0FBQUEsTUFDQSxRQUFRLFVBQVUsVUFBVTtBQUFBLElBQ2hDO0FBQUEsRUFDSjtBQUVBLE1BQUksTUFBTztBQUNQLFlBQVEsSUFBSSxpQ0FBaUM7QUFBQSxFQUNqRDtBQUVBLG9CQUFrQjtBQUNsQixZQUFVO0FBRVYsV0FBUyxpQkFBaUIsb0JBQW9CLFdBQVc7QUFDckQsY0FBVTtBQUFBLEVBQ2QsQ0FBQzsiLAogICJuYW1lcyI6IFsiY2FsbCIsICJjYWxsIiwgImNhbGwiLCAiY2FsbCIsICJjYWxsIiwgImNhbGwiLCAicmVzaXphYmxlIiwgImNhbGwiLCAiZXZlbnROYW1lIiwgImNhbGwiLCAiZ2VuZXJhdGVJRCIsICJFcnJvciIsICJjYWxsIiwgIndpbmRvd05hbWUiLCAiRXJyb3IiXQp9Cg== diff --git a/v3/internal/runtime/runtime_debug_desktop_windows.js b/v3/internal/runtime/runtime_debug_desktop_windows.js deleted file mode 100644 index 1e90fd51115..00000000000 --- a/v3/internal/runtime/runtime_debug_desktop_windows.js +++ /dev/null @@ -1,935 +0,0 @@ -(() => { - var __defProp = Object.defineProperty; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - - // desktop/clipboard.js - var clipboard_exports = {}; - __export(clipboard_exports, { - SetText: () => SetText, - Text: () => Text - }); - - // node_modules/nanoid/non-secure/index.js - var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"; - var nanoid = (size = 21) => { - let id = ""; - let i = size; - while (i--) { - id += urlAlphabet[Math.random() * 64 | 0]; - } - return id; - }; - - // desktop/runtime.js - var runtimeURL = window.location.origin + "/wails/runtime"; - var objectNames = { - Call: 0, - Clipboard: 1, - Application: 2, - Events: 3, - ContextMenu: 4, - Dialog: 5, - Window: 6, - Screens: 7, - System: 8, - Browser: 9 - }; - var clientId = nanoid(); - function runtimeCallWithID(objectID, method, windowName, args) { - let url = new URL(runtimeURL); - url.searchParams.append("object", objectID); - url.searchParams.append("method", method); - let fetchOptions = { - headers: {} - }; - if (windowName) { - fetchOptions.headers["x-wails-window-name"] = windowName; - } - if (args) { - url.searchParams.append("args", JSON.stringify(args)); - } - fetchOptions.headers["x-wails-client-id"] = clientId; - return new Promise((resolve, reject) => { - fetch(url, fetchOptions).then((response) => { - if (response.ok) { - if (response.headers.get("Content-Type") && response.headers.get("Content-Type").indexOf("application/json") !== -1) { - return response.json(); - } else { - return response.text(); - } - } - reject(Error(response.statusText)); - }).then((data) => resolve(data)).catch((error) => reject(error)); - }); - } - function newRuntimeCallerWithID(object, windowName) { - return function(method, args = null) { - return runtimeCallWithID(object, method, windowName, args); - }; - } - - // desktop/clipboard.js - var call = newRuntimeCallerWithID(objectNames.Clipboard); - var ClipboardSetText = 0; - var ClipboardText = 1; - function SetText(text) { - void call(ClipboardSetText, { text }); - } - function Text() { - return call(ClipboardText); - } - - // desktop/application.js - var application_exports = {}; - __export(application_exports, { - Hide: () => Hide, - Quit: () => Quit, - Show: () => Show - }); - var call2 = newRuntimeCallerWithID(objectNames.Application); - var methods = { - Hide: 0, - Show: 1, - Quit: 2 - }; - function Hide() { - void call2(methods.Hide); - } - function Show() { - void call2(methods.Show); - } - function Quit() { - void call2(methods.Quit); - } - - // desktop/screens.js - var screens_exports = {}; - __export(screens_exports, { - GetAll: () => GetAll, - GetCurrent: () => GetCurrent, - GetPrimary: () => GetPrimary - }); - var call3 = newRuntimeCallerWithID(objectNames.Screens); - var ScreensGetAll = 0; - var ScreensGetPrimary = 1; - var ScreensGetCurrent = 2; - function GetAll() { - return call3(ScreensGetAll); - } - function GetPrimary() { - return call3(ScreensGetPrimary); - } - function GetCurrent() { - return call3(ScreensGetCurrent); - } - - // desktop/system.js - var system_exports = {}; - __export(system_exports, { - IsDarkMode: () => IsDarkMode - }); - var call4 = newRuntimeCallerWithID(objectNames.System); - var SystemIsDarkMode = 0; - function IsDarkMode() { - return call4(SystemIsDarkMode); - } - - // desktop/browser.js - var browser_exports = {}; - __export(browser_exports, { - OpenURL: () => OpenURL - }); - var call5 = newRuntimeCallerWithID(objectNames.Browser); - var BrowserOpenURL = 0; - function OpenURL(url) { - void call5(BrowserOpenURL, { url }); - } - - // desktop/calls.js - var call6 = newRuntimeCallerWithID(objectNames.Call); - var CallBinding = 0; - var callResponses = /* @__PURE__ */ new Map(); - function generateID() { - let result; - do { - result = nanoid(); - } while (callResponses.has(result)); - return result; - } - function callCallback(id, data, isJSON) { - let p = callResponses.get(id); - if (p) { - if (isJSON) { - p.resolve(JSON.parse(data)); - } else { - p.resolve(data); - } - callResponses.delete(id); - } - } - function callErrorCallback(id, message) { - let p = callResponses.get(id); - if (p) { - p.reject(message); - callResponses.delete(id); - } - } - function callBinding(type, options) { - return new Promise((resolve, reject) => { - let id = generateID(); - options = options || {}; - options["call-id"] = id; - callResponses.set(id, { resolve, reject }); - call6(type, options).catch((error) => { - reject(error); - callResponses.delete(id); - }); - }); - } - function Call(options) { - return callBinding(CallBinding, options); - } - function CallByName(name, ...args) { - if (typeof name !== "string" || name.split(".").length !== 3) { - throw new Error("CallByName requires a string in the format 'package.struct.method'"); - } - let parts = name.split("."); - return callBinding(CallBinding, { - packageName: parts[0], - structName: parts[1], - methodName: parts[2], - args - }); - } - function CallByID(methodID, ...args) { - return callBinding(CallBinding, { - methodID, - args - }); - } - function Plugin(pluginName, methodName, ...args) { - return callBinding(CallBinding, { - packageName: "wails-plugins", - structName: pluginName, - methodName, - args - }); - } - - // desktop/window.js - var WindowCenter = 0; - var WindowSetTitle = 1; - var WindowFullscreen = 2; - var WindowUnFullscreen = 3; - var WindowSetSize = 4; - var WindowSize = 5; - var WindowSetMaxSize = 6; - var WindowSetMinSize = 7; - var WindowSetAlwaysOnTop = 8; - var WindowSetRelativePosition = 9; - var WindowRelativePosition = 10; - var WindowScreen = 11; - var WindowHide = 12; - var WindowMaximise = 13; - var WindowUnMaximise = 14; - var WindowToggleMaximise = 15; - var WindowMinimise = 16; - var WindowUnMinimise = 17; - var WindowRestore = 18; - var WindowShow = 19; - var WindowClose = 20; - var WindowSetBackgroundColour = 21; - var WindowSetResizable = 22; - var WindowWidth = 23; - var WindowHeight = 24; - var WindowZoomIn = 25; - var WindowZoomOut = 26; - var WindowZoomReset = 27; - var WindowGetZoomLevel = 28; - var WindowSetZoomLevel = 29; - function newWindow(windowName) { - let call10 = newRuntimeCallerWithID(objectNames.Window, windowName); - return { - /** - * Centers the window. - */ - Center: () => void call10(WindowCenter), - /** - * Set the window title. - * @param title - */ - SetTitle: (title) => void call10(WindowSetTitle, { title }), - /** - * Makes the window fullscreen. - */ - Fullscreen: () => void call10(WindowFullscreen), - /** - * Unfullscreen the window. - */ - UnFullscreen: () => void call10(WindowUnFullscreen), - /** - * Set the window size. - * @param {number} width The window width - * @param {number} height The window height - */ - SetSize: (width, height) => call10(WindowSetSize, { width, height }), - /** - * Get the window size. - * @returns {Promise} The window size - */ - Size: () => { - return call10(WindowSize); - }, - /** - * Set the window maximum size. - * @param {number} width - * @param {number} height - */ - SetMaxSize: (width, height) => void call10(WindowSetMaxSize, { width, height }), - /** - * Set the window minimum size. - * @param {number} width - * @param {number} height - */ - SetMinSize: (width, height) => void call10(WindowSetMinSize, { width, height }), - /** - * Set window to be always on top. - * @param {boolean} onTop Whether the window should be always on top - */ - SetAlwaysOnTop: (onTop) => void call10(WindowSetAlwaysOnTop, { alwaysOnTop: onTop }), - /** - * Set the window relative position. - * @param {number} x - * @param {number} y - */ - SetRelativePosition: (x, y) => call10(WindowSetRelativePosition, { x, y }), - /** - * Get the window position. - * @returns {Promise} The window position - */ - RelativePosition: () => { - return call10(WindowRelativePosition); - }, - /** - * Get the screen the window is on. - * @returns {Promise} - */ - Screen: () => { - return call10(WindowScreen); - }, - /** - * Hide the window - */ - Hide: () => void call10(WindowHide), - /** - * Maximise the window - */ - Maximise: () => void call10(WindowMaximise), - /** - * Show the window - */ - Show: () => void call10(WindowShow), - /** - * Close the window - */ - Close: () => void call10(WindowClose), - /** - * Toggle the window maximise state - */ - ToggleMaximise: () => void call10(WindowToggleMaximise), - /** - * Unmaximise the window - */ - UnMaximise: () => void call10(WindowUnMaximise), - /** - * Minimise the window - */ - Minimise: () => void call10(WindowMinimise), - /** - * Unminimise the window - */ - UnMinimise: () => void call10(WindowUnMinimise), - /** - * Restore the window - */ - Restore: () => void call10(WindowRestore), - /** - * Set the background colour of the window. - * @param {number} r - A value between 0 and 255 - * @param {number} g - A value between 0 and 255 - * @param {number} b - A value between 0 and 255 - * @param {number} a - A value between 0 and 255 - */ - SetBackgroundColour: (r, g, b, a) => void call10(WindowSetBackgroundColour, { r, g, b, a }), - /** - * Set whether the window can be resized or not - * @param {boolean} resizable - */ - SetResizable: (resizable2) => void call10(WindowSetResizable, { resizable: resizable2 }), - /** - * Get the window width - * @returns {Promise} - */ - Width: () => { - return call10(WindowWidth); - }, - /** - * Get the window height - * @returns {Promise} - */ - Height: () => { - return call10(WindowHeight); - }, - /** - * Zoom in the window - */ - ZoomIn: () => void call10(WindowZoomIn), - /** - * Zoom out the window - */ - ZoomOut: () => void call10(WindowZoomOut), - /** - * Reset the window zoom - */ - ZoomReset: () => void call10(WindowZoomReset), - /** - * Get the window zoom - * @returns {Promise} - */ - GetZoomLevel: () => { - return call10(WindowGetZoomLevel); - }, - /** - * Set the window zoom level - * @param {number} zoomLevel - */ - SetZoomLevel: (zoomLevel) => void call10(WindowSetZoomLevel, { zoomLevel }) - }; - } - - // desktop/events.js - var call7 = newRuntimeCallerWithID(objectNames.Events); - var EventEmit = 0; - var Listener = class { - /** - * Creates an instance of Listener. - * @param {string} eventName - * @param {function} callback - * @param {number} maxCallbacks - * @memberof Listener - */ - constructor(eventName, callback, maxCallbacks) { - this.eventName = eventName; - this.maxCallbacks = maxCallbacks || -1; - this.Callback = (data) => { - callback(data); - if (this.maxCallbacks === -1) { - return false; - } - this.maxCallbacks -= 1; - return this.maxCallbacks === 0; - }; - } - }; - var WailsEvent = class { - /** - * Creates an instance of WailsEvent. - * @param {string} name - Name of the event - * @param {any=null} data - Data associated with the event - * @memberof WailsEvent - */ - constructor(name, data = null) { - this.name = name; - this.data = data; - } - }; - var eventListeners = /* @__PURE__ */ new Map(); - function OnMultiple(eventName, callback, maxCallbacks) { - let listeners = eventListeners.get(eventName) || []; - const thisListener = new Listener(eventName, callback, maxCallbacks); - listeners.push(thisListener); - eventListeners.set(eventName, listeners); - return () => listenerOff(thisListener); - } - function On(eventName, callback) { - return OnMultiple(eventName, callback, -1); - } - function Once(eventName, callback) { - return OnMultiple(eventName, callback, 1); - } - function listenerOff(listener) { - const eventName = listener.eventName; - let listeners = eventListeners.get(eventName).filter((l) => l !== listener); - if (listeners.length === 0) { - eventListeners.delete(eventName); - } else { - eventListeners.set(eventName, listeners); - } - } - function dispatchWailsEvent(event) { - let listeners = eventListeners.get(event.name); - if (listeners) { - let toRemove = []; - listeners.forEach((listener) => { - let remove = listener.Callback(event); - if (remove) { - toRemove.push(listener); - } - }); - if (toRemove.length > 0) { - listeners = listeners.filter((l) => !toRemove.includes(l)); - if (listeners.length === 0) { - eventListeners.delete(event.name); - } else { - eventListeners.set(event.name, listeners); - } - } - } - } - function Off(eventName, ...additionalEventNames) { - let eventsToRemove = [eventName, ...additionalEventNames]; - eventsToRemove.forEach((eventName2) => { - eventListeners.delete(eventName2); - }); - } - function OffAll() { - eventListeners.clear(); - } - function Emit(event) { - void call7(EventEmit, event); - } - - // desktop/dialogs.js - var call8 = newRuntimeCallerWithID(objectNames.Dialog); - var DialogInfo = 0; - var DialogWarning = 1; - var DialogError = 2; - var DialogQuestion = 3; - var DialogOpenFile = 4; - var DialogSaveFile = 5; - var dialogResponses = /* @__PURE__ */ new Map(); - function generateID2() { - let result; - do { - result = nanoid(); - } while (dialogResponses.has(result)); - return result; - } - function dialogCallback(id, data, isJSON) { - let p = dialogResponses.get(id); - if (p) { - if (isJSON) { - p.resolve(JSON.parse(data)); - } else { - p.resolve(data); - } - dialogResponses.delete(id); - } - } - function dialogErrorCallback(id, message) { - let p = dialogResponses.get(id); - if (p) { - p.reject(message); - dialogResponses.delete(id); - } - } - function dialog(type, options) { - return new Promise((resolve, reject) => { - let id = generateID2(); - options = options || {}; - options["dialog-id"] = id; - dialogResponses.set(id, { resolve, reject }); - call8(type, options).catch((error) => { - reject(error); - dialogResponses.delete(id); - }); - }); - } - function Info(options) { - return dialog(DialogInfo, options); - } - function Warning(options) { - return dialog(DialogWarning, options); - } - function Error2(options) { - return dialog(DialogError, options); - } - function Question(options) { - return dialog(DialogQuestion, options); - } - function OpenFile(options) { - return dialog(DialogOpenFile, options); - } - function SaveFile(options) { - return dialog(DialogSaveFile, options); - } - - // desktop/contextmenu.js - var call9 = newRuntimeCallerWithID(objectNames.ContextMenu); - var ContextMenuOpen = 0; - function openContextMenu(id, x, y, data) { - void call9(ContextMenuOpen, { id, x, y, data }); - } - function setupContextMenus() { - window.addEventListener("contextmenu", contextMenuHandler); - } - function contextMenuHandler(event) { - let element = event.target; - let customContextMenu = window.getComputedStyle(element).getPropertyValue("--custom-contextmenu"); - customContextMenu = customContextMenu ? customContextMenu.trim() : ""; - if (customContextMenu) { - event.preventDefault(); - let customContextMenuData = window.getComputedStyle(element).getPropertyValue("--custom-contextmenu-data"); - openContextMenu(customContextMenu, event.clientX, event.clientY, customContextMenuData); - return; - } - processDefaultContextMenu(event); - } - function processDefaultContextMenu(event) { - if (true) { - return; - } - const element = event.target; - const computedStyle = window.getComputedStyle(element); - const defaultContextMenuAction = computedStyle.getPropertyValue("--default-contextmenu").trim(); - switch (defaultContextMenuAction) { - case "show": - return; - case "hide": - event.preventDefault(); - return; - default: - if (element.isContentEditable) { - return; - } - const selection = window.getSelection(); - const hasSelection = selection.toString().length > 0; - if (hasSelection) { - for (let i = 0; i < selection.rangeCount; i++) { - const range = selection.getRangeAt(i); - const rects = range.getClientRects(); - for (let j = 0; j < rects.length; j++) { - const rect = rects[j]; - if (document.elementFromPoint(rect.left, rect.top) === element) { - return; - } - } - } - } - if (element.tagName === "INPUT" || element.tagName === "TEXTAREA") { - if (hasSelection || !element.readOnly && !element.disabled) { - return; - } - } - event.preventDefault(); - } - } - - // desktop/wml.js - function sendEvent(eventName, data = null) { - let event = new WailsEvent(eventName, data); - Emit(event); - } - function addWMLEventListeners() { - const elements = document.querySelectorAll("[wml-event]"); - elements.forEach(function(element) { - const eventType = element.getAttribute("wml-event"); - const confirm = element.getAttribute("wml-confirm"); - const trigger = element.getAttribute("wml-trigger") || "click"; - let callback = function() { - if (confirm) { - Question({ Title: "Confirm", Message: confirm, Detached: false, Buttons: [{ Label: "Yes" }, { Label: "No", IsDefault: true }] }).then(function(result) { - if (result !== "No") { - sendEvent(eventType); - } - }); - return; - } - sendEvent(eventType); - }; - element.removeEventListener(trigger, callback); - element.addEventListener(trigger, callback); - }); - } - function callWindowMethod(method) { - if (wails.Window[method] === void 0) { - console.log("Window method " + method + " not found"); - } - wails.Window[method](); - } - function addWMLWindowListeners() { - const elements = document.querySelectorAll("[wml-window]"); - elements.forEach(function(element) { - const windowMethod = element.getAttribute("wml-window"); - const confirm = element.getAttribute("wml-confirm"); - const trigger = element.getAttribute("wml-trigger") || "click"; - let callback = function() { - if (confirm) { - Question({ Title: "Confirm", Message: confirm, Buttons: [{ Label: "Yes" }, { Label: "No", IsDefault: true }] }).then(function(result) { - if (result !== "No") { - callWindowMethod(windowMethod); - } - }); - return; - } - callWindowMethod(windowMethod); - }; - element.removeEventListener(trigger, callback); - element.addEventListener(trigger, callback); - }); - } - function addWMLOpenBrowserListener() { - const elements = document.querySelectorAll("[wml-openurl]"); - elements.forEach(function(element) { - const url = element.getAttribute("wml-openurl"); - const confirm = element.getAttribute("wml-confirm"); - const trigger = element.getAttribute("wml-trigger") || "click"; - let callback = function() { - if (confirm) { - Question({ Title: "Confirm", Message: confirm, Buttons: [{ Label: "Yes" }, { Label: "No", IsDefault: true }] }).then(function(result) { - if (result !== "No") { - void wails.Browser.OpenURL(url); - } - }); - return; - } - void wails.Browser.OpenURL(url); - }; - element.removeEventListener(trigger, callback); - element.addEventListener(trigger, callback); - }); - } - function reloadWML() { - addWMLEventListeners(); - addWMLWindowListeners(); - addWMLOpenBrowserListener(); - } - - // desktop/invoke.js - var invoke = function(input) { - if (true) { - chrome.webview.postMessage(input); - } else { - webkit.messageHandlers.external.postMessage(input); - } - }; - - // desktop/flags.js - var flags = /* @__PURE__ */ new Map(); - function convertToMap(obj) { - const map = /* @__PURE__ */ new Map(); - for (const [key, value] of Object.entries(obj)) { - if (typeof value === "object" && value !== null) { - map.set(key, convertToMap(value)); - } else { - map.set(key, value); - } - } - return map; - } - fetch("/wails/flags").then((response) => { - response.json().then((data) => { - flags = convertToMap(data); - }); - }); - function getValueFromMap(keyString) { - const keys = keyString.split("."); - let value = flags; - for (const key of keys) { - if (value instanceof Map) { - value = value.get(key); - } else { - value = value[key]; - } - if (value === void 0) { - break; - } - } - return value; - } - function GetFlag(keyString) { - return getValueFromMap(keyString); - } - - // desktop/drag.js - var shouldDrag = false; - function dragTest(e) { - let val = window.getComputedStyle(e.target).getPropertyValue("--webkit-app-region"); - if (val) { - val = val.trim(); - } - if (val !== "drag") { - return false; - } - if (e.buttons !== 1) { - return false; - } - return e.detail === 1; - } - function setupDrag() { - window.addEventListener("mousedown", onMouseDown); - window.addEventListener("mousemove", onMouseMove); - window.addEventListener("mouseup", onMouseUp); - } - var resizeEdge = null; - var resizable = false; - function setResizable(value) { - resizable = value; - } - function testResize(e) { - if (resizeEdge) { - invoke("resize:" + resizeEdge); - return true; - } - return false; - } - function onMouseDown(e) { - if (true) { - if (testResize()) { - return; - } - } - if (dragTest(e)) { - if (e.offsetX > e.target.clientWidth || e.offsetY > e.target.clientHeight) { - return; - } - shouldDrag = true; - } else { - shouldDrag = false; - } - } - function onMouseUp(e) { - let mousePressed = e.buttons !== void 0 ? e.buttons : e.which; - if (mousePressed > 0) { - endDrag(); - } - } - function endDrag() { - document.body.style.cursor = "default"; - shouldDrag = false; - } - function setResize(cursor) { - document.documentElement.style.cursor = cursor || defaultCursor; - resizeEdge = cursor; - } - function onMouseMove(e) { - if (shouldDrag) { - shouldDrag = false; - let mousePressed = e.buttons !== void 0 ? e.buttons : e.which; - if (mousePressed > 0) { - invoke("drag"); - } - return; - } - if (true) { - if (resizable) { - handleResize(e); - } - } - } - var defaultCursor = "auto"; - function handleResize(e) { - let resizeHandleHeight = GetFlag("system.resizeHandleHeight") || 5; - let resizeHandleWidth = GetFlag("system.resizeHandleWidth") || 5; - let cornerExtra = GetFlag("resizeCornerExtra") || 10; - let rightBorder = window.outerWidth - e.clientX < resizeHandleWidth; - let leftBorder = e.clientX < resizeHandleWidth; - let topBorder = e.clientY < resizeHandleHeight; - let bottomBorder = window.outerHeight - e.clientY < resizeHandleHeight; - let rightCorner = window.outerWidth - e.clientX < resizeHandleWidth + cornerExtra; - let leftCorner = e.clientX < resizeHandleWidth + cornerExtra; - let topCorner = e.clientY < resizeHandleHeight + cornerExtra; - let bottomCorner = window.outerHeight - e.clientY < resizeHandleHeight + cornerExtra; - if (!leftBorder && !rightBorder && !topBorder && !bottomBorder && resizeEdge !== void 0) { - setResize(); - } else if (rightCorner && bottomCorner) - setResize("se-resize"); - else if (leftCorner && bottomCorner) - setResize("sw-resize"); - else if (leftCorner && topCorner) - setResize("nw-resize"); - else if (topCorner && rightCorner) - setResize("ne-resize"); - else if (leftBorder) - setResize("w-resize"); - else if (topBorder) - setResize("n-resize"); - else if (bottomBorder) - setResize("s-resize"); - else if (rightBorder) - setResize("e-resize"); - } - - // desktop/main.js - window.wails = { - ...newRuntime(null), - Capabilities: {}, - clientId - }; - fetch("/wails/capabilities").then((response) => { - response.json().then((data) => { - window.wails.Capabilities = data; - }); - }); - window._wails = { - dialogCallback, - dialogErrorCallback, - dispatchWailsEvent, - callCallback, - callErrorCallback, - endDrag, - setResizable - }; - function newRuntime(windowName) { - return { - Clipboard: { - ...clipboard_exports - }, - Application: { - ...application_exports, - GetWindowByName(windowName2) { - return newRuntime(windowName2); - } - }, - System: system_exports, - Screens: screens_exports, - Browser: browser_exports, - Call, - CallByID, - CallByName, - Plugin, - WML: { - Reload: reloadWML - }, - Dialog: { - Info, - Warning, - Error: Error2, - Question, - OpenFile, - SaveFile - }, - Events: { - Emit, - On, - Once, - OnMultiple, - Off, - OffAll - }, - Window: newWindow(windowName) - }; - } - if (true) { - console.log("Wails v3.0.0 Debug Mode Enabled"); - } - setupContextMenus(); - setupDrag(); - document.addEventListener("DOMContentLoaded", function() { - reloadWML(); - }); -})(); -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiZGVza3RvcC9jbGlwYm9hcmQuanMiLCAibm9kZV9tb2R1bGVzL25hbm9pZC9ub24tc2VjdXJlL2luZGV4LmpzIiwgImRlc2t0b3AvcnVudGltZS5qcyIsICJkZXNrdG9wL2FwcGxpY2F0aW9uLmpzIiwgImRlc2t0b3Avc2NyZWVucy5qcyIsICJkZXNrdG9wL3N5c3RlbS5qcyIsICJkZXNrdG9wL2Jyb3dzZXIuanMiLCAiZGVza3RvcC9jYWxscy5qcyIsICJkZXNrdG9wL3dpbmRvdy5qcyIsICJkZXNrdG9wL2V2ZW50cy5qcyIsICJkZXNrdG9wL2RpYWxvZ3MuanMiLCAiZGVza3RvcC9jb250ZXh0bWVudS5qcyIsICJkZXNrdG9wL3dtbC5qcyIsICJkZXNrdG9wL2ludm9rZS5qcyIsICJkZXNrdG9wL2ZsYWdzLmpzIiwgImRlc2t0b3AvZHJhZy5qcyIsICJkZXNrdG9wL21haW4uanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmxldCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5DbGlwYm9hcmQpO1xyXG5cclxubGV0IENsaXBib2FyZFNldFRleHQgPSAwO1xyXG5sZXQgQ2xpcGJvYXJkVGV4dCA9IDE7XHJcblxyXG4vKipcclxuICogU2V0IHRoZSBDbGlwYm9hcmQgdGV4dFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIFNldFRleHQodGV4dCkge1xyXG4gICAgdm9pZCBjYWxsKENsaXBib2FyZFNldFRleHQsIHt0ZXh0fSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgdGhlIENsaXBib2FyZCB0ZXh0XHJcbiAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZz59XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gVGV4dCgpIHtcclxuICAgIHJldHVybiBjYWxsKENsaXBib2FyZFRleHQpO1xyXG59IiwgImxldCB1cmxBbHBoYWJldCA9XG4gICd1c2VhbmRvbS0yNlQxOTgzNDBQWDc1cHhKQUNLVkVSWU1JTkRCVVNIV09MRl9HUVpiZmdoamtscXZ3eXpyaWN0J1xuZXhwb3J0IGxldCBjdXN0b21BbHBoYWJldCA9IChhbHBoYWJldCwgZGVmYXVsdFNpemUgPSAyMSkgPT4ge1xuICByZXR1cm4gKHNpemUgPSBkZWZhdWx0U2l6ZSkgPT4ge1xuICAgIGxldCBpZCA9ICcnXG4gICAgbGV0IGkgPSBzaXplXG4gICAgd2hpbGUgKGktLSkge1xuICAgICAgaWQgKz0gYWxwaGFiZXRbKE1hdGgucmFuZG9tKCkgKiBhbHBoYWJldC5sZW5ndGgpIHwgMF1cbiAgICB9XG4gICAgcmV0dXJuIGlkXG4gIH1cbn1cbmV4cG9ydCBsZXQgbmFub2lkID0gKHNpemUgPSAyMSkgPT4ge1xuICBsZXQgaWQgPSAnJ1xuICBsZXQgaSA9IHNpemVcbiAgd2hpbGUgKGktLSkge1xuICAgIGlkICs9IHVybEFscGhhYmV0WyhNYXRoLnJhbmRvbSgpICogNjQpIHwgMF1cbiAgfVxuICByZXR1cm4gaWRcbn1cbiIsICIvKlxyXG4gXyAgICAgX18gICAgIF8gX19cclxufCB8ICAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcbmltcG9ydCB7IG5hbm9pZCB9IGZyb20gJ25hbm9pZC9ub24tc2VjdXJlJztcclxuXHJcbmNvbnN0IHJ1bnRpbWVVUkwgPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luICsgXCIvd2FpbHMvcnVudGltZVwiO1xyXG4vLyBPYmplY3QgTmFtZXNcclxuZXhwb3J0IGNvbnN0IG9iamVjdE5hbWVzID0ge1xyXG4gICAgQ2FsbDogMCxcclxuICAgIENsaXBib2FyZDogMSxcclxuICAgIEFwcGxpY2F0aW9uOiAyLFxyXG4gICAgRXZlbnRzOiAzLFxyXG4gICAgQ29udGV4dE1lbnU6IDQsXHJcbiAgICBEaWFsb2c6IDUsXHJcbiAgICBXaW5kb3c6IDYsXHJcbiAgICBTY3JlZW5zOiA3LFxyXG4gICAgU3lzdGVtOiA4LFxyXG4gICAgQnJvd3NlcjogOSxcclxufVxyXG5leHBvcnQgbGV0IGNsaWVudElkID0gbmFub2lkKCk7XHJcblxyXG5mdW5jdGlvbiBydW50aW1lQ2FsbChtZXRob2QsIHdpbmRvd05hbWUsIGFyZ3MpIHtcclxuICAgIGxldCB1cmwgPSBuZXcgVVJMKHJ1bnRpbWVVUkwpO1xyXG4gICAgaWYoIG1ldGhvZCApIHtcclxuICAgICAgICB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChcIm1ldGhvZFwiLCBtZXRob2QpO1xyXG4gICAgfVxyXG4gICAgbGV0IGZldGNoT3B0aW9ucyA9IHtcclxuICAgICAgICBoZWFkZXJzOiB7fSxcclxuICAgIH07XHJcbiAgICBpZiAod2luZG93TmFtZSkge1xyXG4gICAgICAgIGZldGNoT3B0aW9ucy5oZWFkZXJzW1wieC13YWlscy13aW5kb3ctbmFtZVwiXSA9IHdpbmRvd05hbWU7XHJcbiAgICB9XHJcbiAgICBpZiAoYXJncykge1xyXG4gICAgICAgIHVybC5zZWFyY2hQYXJhbXMuYXBwZW5kKFwiYXJnc1wiLCBKU09OLnN0cmluZ2lmeShhcmdzKSk7XHJcbiAgICB9XHJcbiAgICBmZXRjaE9wdGlvbnMuaGVhZGVyc1tcIngtd2FpbHMtY2xpZW50LWlkXCJdID0gY2xpZW50SWQ7XHJcblxyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICBmZXRjaCh1cmwsIGZldGNoT3B0aW9ucylcclxuICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgY29udGVudCB0eXBlXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiQ29udGVudC1UeXBlXCIpICYmIHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiQ29udGVudC1UeXBlXCIpLmluZGV4T2YoXCJhcHBsaWNhdGlvbi9qc29uXCIpICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZS50ZXh0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKHJlc3BvbnNlLnN0YXR1c1RleHQpKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLnRoZW4oZGF0YSA9PiByZXNvbHZlKGRhdGEpKVxyXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIG5ld1J1bnRpbWVDYWxsZXIob2JqZWN0LCB3aW5kb3dOYW1lKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKG1ldGhvZCwgYXJncz1udWxsKSB7XHJcbiAgICAgICAgcmV0dXJuIHJ1bnRpbWVDYWxsKG9iamVjdCArIFwiLlwiICsgbWV0aG9kLCB3aW5kb3dOYW1lLCBhcmdzKTtcclxuICAgIH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJ1bnRpbWVDYWxsV2l0aElEKG9iamVjdElELCBtZXRob2QsIHdpbmRvd05hbWUsIGFyZ3MpIHtcclxuICAgIGxldCB1cmwgPSBuZXcgVVJMKHJ1bnRpbWVVUkwpO1xyXG4gICAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoXCJvYmplY3RcIiwgb2JqZWN0SUQpO1xyXG4gICAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoXCJtZXRob2RcIiwgbWV0aG9kKTtcclxuICAgIGxldCBmZXRjaE9wdGlvbnMgPSB7XHJcbiAgICAgICAgaGVhZGVyczoge30sXHJcbiAgICB9O1xyXG4gICAgaWYgKHdpbmRvd05hbWUpIHtcclxuICAgICAgICBmZXRjaE9wdGlvbnMuaGVhZGVyc1tcIngtd2FpbHMtd2luZG93LW5hbWVcIl0gPSB3aW5kb3dOYW1lO1xyXG4gICAgfVxyXG4gICAgaWYgKGFyZ3MpIHtcclxuICAgICAgICB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChcImFyZ3NcIiwgSlNPTi5zdHJpbmdpZnkoYXJncykpO1xyXG4gICAgfVxyXG4gICAgZmV0Y2hPcHRpb25zLmhlYWRlcnNbXCJ4LXdhaWxzLWNsaWVudC1pZFwiXSA9IGNsaWVudElkO1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICBmZXRjaCh1cmwsIGZldGNoT3B0aW9ucylcclxuICAgICAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLm9rKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gY2hlY2sgY29udGVudCB0eXBlXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiQ29udGVudC1UeXBlXCIpICYmIHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiQ29udGVudC1UeXBlXCIpLmluZGV4T2YoXCJhcHBsaWNhdGlvbi9qc29uXCIpICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzcG9uc2UuanNvbigpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZS50ZXh0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKHJlc3BvbnNlLnN0YXR1c1RleHQpKTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLnRoZW4oZGF0YSA9PiByZXNvbHZlKGRhdGEpKVxyXG4gICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4gcmVqZWN0KGVycm9yKSk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIG5ld1J1bnRpbWVDYWxsZXJXaXRoSUQob2JqZWN0LCB3aW5kb3dOYW1lKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKG1ldGhvZCwgYXJncz1udWxsKSB7XHJcbiAgICAgICAgcmV0dXJuIHJ1bnRpbWVDYWxsV2l0aElEKG9iamVjdCwgbWV0aG9kLCB3aW5kb3dOYW1lLCBhcmdzKTtcclxuICAgIH07XHJcbn1cclxuIiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmxldCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5BcHBsaWNhdGlvbik7XHJcblxyXG5sZXQgbWV0aG9kcyA9IHtcclxuICAgIEhpZGU6IDAsXHJcbiAgICBTaG93OiAxLFxyXG4gICAgUXVpdDogMixcclxufVxyXG5cclxuLyoqXHJcbiAqIEhpZGUgdGhlIGFwcGxpY2F0aW9uXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gSGlkZSgpIHtcclxuICAgIHZvaWQgY2FsbChtZXRob2RzLkhpZGUpO1xyXG59XHJcblxyXG4vKipcclxuICogU2hvdyB0aGUgYXBwbGljYXRpb25cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBTaG93KCkge1xyXG4gICAgdm9pZCBjYWxsKG1ldGhvZHMuU2hvdyk7XHJcbn1cclxuXHJcblxyXG4vKipcclxuICogUXVpdCB0aGUgYXBwbGljYXRpb25cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBRdWl0KCkge1xyXG4gICAgdm9pZCBjYWxsKG1ldGhvZHMuUXVpdCk7XHJcbn0iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuLyoganNoaW50IGVzdmVyc2lvbjogOSAqL1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL2FwaS90eXBlc1wiKS5TY3JlZW59IFNjcmVlblxyXG4gKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmxldCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5TY3JlZW5zKTtcclxuXHJcbmxldCBTY3JlZW5zR2V0QWxsID0gMDtcclxubGV0IFNjcmVlbnNHZXRQcmltYXJ5ID0gMTtcclxubGV0IFNjcmVlbnNHZXRDdXJyZW50ID0gMjtcclxuXHJcbi8qKlxyXG4gKiBHZXRzIGFsbCBzY3JlZW5zLlxyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxTY3JlZW5bXT59XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gR2V0QWxsKCkge1xyXG4gICAgcmV0dXJuIGNhbGwoU2NyZWVuc0dldEFsbCk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBwcmltYXJ5IHNjcmVlbi5cclxuICogQHJldHVybnMge1Byb21pc2U8U2NyZWVuPn1cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBHZXRQcmltYXJ5KCkge1xyXG4gICAgcmV0dXJuIGNhbGwoU2NyZWVuc0dldFByaW1hcnkpO1xyXG59XHJcblxyXG4vKipcclxuICogR2V0cyB0aGUgY3VycmVudCBhY3RpdmUgc2NyZWVuLlxyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxTY3JlZW4+fVxyXG4gKiBAY29uc3RydWN0b3JcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBHZXRDdXJyZW50KCkge1xyXG4gICAgcmV0dXJuIGNhbGwoU2NyZWVuc0dldEN1cnJlbnQpO1xyXG59IiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmxldCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5TeXN0ZW0pO1xyXG5cclxubGV0IFN5c3RlbUlzRGFya01vZGUgPSAwO1xyXG5cclxuLyoqXHJcbiAqIERldGVybWluZXMgaWYgdGhlIHN5c3RlbSBpcyBjdXJyZW50bHkgdXNpbmcgZGFyayBtb2RlXHJcbiAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIElzRGFya01vZGUoKSB7XHJcbiAgICByZXR1cm4gY2FsbChTeXN0ZW1Jc0RhcmtNb2RlKTtcclxufSIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcblxyXG5pbXBvcnQge25ld1J1bnRpbWVDYWxsZXJXaXRoSUQsIG9iamVjdE5hbWVzfSBmcm9tIFwiLi9ydW50aW1lXCI7XHJcblxyXG5sZXQgY2FsbCA9IG5ld1J1bnRpbWVDYWxsZXJXaXRoSUQob2JqZWN0TmFtZXMuQnJvd3Nlcik7XHJcblxyXG5sZXQgQnJvd3Nlck9wZW5VUkwgPSAwO1xyXG5cclxuLyoqXHJcbiAqIE9wZW4gYSBicm93c2VyIHdpbmRvdyB0byB0aGUgZ2l2ZW4gVVJMXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgLSBUaGUgVVJMIHRvIG9wZW5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBPcGVuVVJMKHVybCkge1xyXG4gICAgdm9pZCBjYWxsKEJyb3dzZXJPcGVuVVJMLCB7dXJsfSk7XHJcbn1cclxuIiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmltcG9ydCB7IG5hbm9pZCB9IGZyb20gJ25hbm9pZC9ub24tc2VjdXJlJztcclxuXHJcbmxldCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5DYWxsKTtcclxuXHJcbmxldCBDYWxsQmluZGluZyA9IDA7XHJcblxyXG5sZXQgY2FsbFJlc3BvbnNlcyA9IG5ldyBNYXAoKTtcclxuXHJcbmZ1bmN0aW9uIGdlbmVyYXRlSUQoKSB7XHJcbiAgICBsZXQgcmVzdWx0O1xyXG4gICAgZG8ge1xyXG4gICAgICAgIHJlc3VsdCA9IG5hbm9pZCgpO1xyXG4gICAgfSB3aGlsZSAoY2FsbFJlc3BvbnNlcy5oYXMocmVzdWx0KSk7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY2FsbENhbGxiYWNrKGlkLCBkYXRhLCBpc0pTT04pIHtcclxuICAgIGxldCBwID0gY2FsbFJlc3BvbnNlcy5nZXQoaWQpO1xyXG4gICAgaWYgKHApIHtcclxuICAgICAgICBpZiAoaXNKU09OKSB7XHJcbiAgICAgICAgICAgIHAucmVzb2x2ZShKU09OLnBhcnNlKGRhdGEpKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBwLnJlc29sdmUoZGF0YSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhbGxSZXNwb25zZXMuZGVsZXRlKGlkKTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGNhbGxFcnJvckNhbGxiYWNrKGlkLCBtZXNzYWdlKSB7XHJcbiAgICBsZXQgcCA9IGNhbGxSZXNwb25zZXMuZ2V0KGlkKTtcclxuICAgIGlmIChwKSB7XHJcbiAgICAgICAgcC5yZWplY3QobWVzc2FnZSk7XHJcbiAgICAgICAgY2FsbFJlc3BvbnNlcy5kZWxldGUoaWQpO1xyXG4gICAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBjYWxsQmluZGluZyh0eXBlLCBvcHRpb25zKSB7XHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgIGxldCBpZCA9IGdlbmVyYXRlSUQoKTtcclxuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcclxuICAgICAgICBvcHRpb25zW1wiY2FsbC1pZFwiXSA9IGlkO1xyXG5cclxuICAgICAgICBjYWxsUmVzcG9uc2VzLnNldChpZCwge3Jlc29sdmUsIHJlamVjdH0pO1xyXG4gICAgICAgIGNhbGwodHlwZSwgb3B0aW9ucykuY2F0Y2goKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAgIHJlamVjdChlcnJvcik7XHJcbiAgICAgICAgICAgIGNhbGxSZXNwb25zZXMuZGVsZXRlKGlkKTtcclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gQ2FsbChvcHRpb25zKSB7XHJcbiAgICByZXR1cm4gY2FsbEJpbmRpbmcoQ2FsbEJpbmRpbmcsIG9wdGlvbnMpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gQ2FsbEJ5TmFtZShuYW1lLCAuLi5hcmdzKSB7XHJcblxyXG4gICAgLy8gRW5zdXJlIGZpcnN0IGFyZ3VtZW50IGlzIGEgc3RyaW5nIGFuZCBoYXMgMiBkb3RzXHJcbiAgICBpZiAodHlwZW9mIG5hbWUgIT09IFwic3RyaW5nXCIgfHwgbmFtZS5zcGxpdChcIi5cIikubGVuZ3RoICE9PSAzKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2FsbEJ5TmFtZSByZXF1aXJlcyBhIHN0cmluZyBpbiB0aGUgZm9ybWF0ICdwYWNrYWdlLnN0cnVjdC5tZXRob2QnXCIpO1xyXG4gICAgfVxyXG4gICAgLy8gU3BsaXQgaW5wdXRzXHJcbiAgICBsZXQgcGFydHMgPSBuYW1lLnNwbGl0KFwiLlwiKTtcclxuXHJcbiAgICByZXR1cm4gY2FsbEJpbmRpbmcoQ2FsbEJpbmRpbmcsIHtcclxuICAgICAgICBwYWNrYWdlTmFtZTogcGFydHNbMF0sXHJcbiAgICAgICAgc3RydWN0TmFtZTogcGFydHNbMV0sXHJcbiAgICAgICAgbWV0aG9kTmFtZTogcGFydHNbMl0sXHJcbiAgICAgICAgYXJnczogYXJncyxcclxuICAgIH0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gQ2FsbEJ5SUQobWV0aG9kSUQsIC4uLmFyZ3MpIHtcclxuICAgIHJldHVybiBjYWxsQmluZGluZyhDYWxsQmluZGluZywge1xyXG4gICAgICAgIG1ldGhvZElEOiBtZXRob2RJRCxcclxuICAgICAgICBhcmdzOiBhcmdzLFxyXG4gICAgfSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDYWxsIGEgcGx1Z2luIG1ldGhvZFxyXG4gKiBAcGFyYW0ge3N0cmluZ30gcGx1Z2luTmFtZSAtIG5hbWUgb2YgdGhlIHBsdWdpblxyXG4gKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kTmFtZSAtIG5hbWUgb2YgdGhlIG1ldGhvZFxyXG4gKiBAcGFyYW0gey4uLmFueX0gYXJncyAtIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBtZXRob2RcclxuICogQHJldHVybnMge1Byb21pc2U8YW55Pn0gLSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgcmVzdWx0XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gUGx1Z2luKHBsdWdpbk5hbWUsIG1ldGhvZE5hbWUsIC4uLmFyZ3MpIHtcclxuICAgIHJldHVybiBjYWxsQmluZGluZyhDYWxsQmluZGluZywge1xyXG4gICAgICAgIHBhY2thZ2VOYW1lOiBcIndhaWxzLXBsdWdpbnNcIixcclxuICAgICAgICBzdHJ1Y3ROYW1lOiBwbHVnaW5OYW1lLFxyXG4gICAgICAgIG1ldGhvZE5hbWU6IG1ldGhvZE5hbWUsXHJcbiAgICAgICAgYXJnczogYXJncyxcclxuICAgIH0pO1xyXG59IiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbi8qKlxyXG4gKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi4vYXBpL3R5cGVzXCIpLlNpemV9IFNpemVcclxuICogQHR5cGVkZWYge2ltcG9ydChcIi4uL2FwaS90eXBlc1wiKS5Qb3NpdGlvbn0gUG9zaXRpb25cclxuICogQHR5cGVkZWYge2ltcG9ydChcIi4uL2FwaS90eXBlc1wiKS5TY3JlZW59IFNjcmVlblxyXG4gKi9cclxuXHJcbmltcG9ydCB7bmV3UnVudGltZUNhbGxlcldpdGhJRCwgb2JqZWN0TmFtZXN9IGZyb20gXCIuL3J1bnRpbWVcIjtcclxuXHJcbmxldCBXaW5kb3dDZW50ZXIgPSAwO1xyXG5sZXQgV2luZG93U2V0VGl0bGUgPSAxO1xyXG5sZXQgV2luZG93RnVsbHNjcmVlbiA9IDI7XHJcbmxldCBXaW5kb3dVbkZ1bGxzY3JlZW4gPSAzO1xyXG5sZXQgV2luZG93U2V0U2l6ZSA9IDQ7XHJcbmxldCBXaW5kb3dTaXplID0gNTtcclxubGV0IFdpbmRvd1NldE1heFNpemUgPSA2O1xyXG5sZXQgV2luZG93U2V0TWluU2l6ZSA9IDc7XHJcbmxldCBXaW5kb3dTZXRBbHdheXNPblRvcCA9IDg7XHJcbmxldCBXaW5kb3dTZXRSZWxhdGl2ZVBvc2l0aW9uID0gOTtcclxubGV0IFdpbmRvd1JlbGF0aXZlUG9zaXRpb24gPSAxMDtcclxubGV0IFdpbmRvd1NjcmVlbiA9IDExO1xyXG5sZXQgV2luZG93SGlkZSA9IDEyO1xyXG5sZXQgV2luZG93TWF4aW1pc2UgPSAxMztcclxubGV0IFdpbmRvd1VuTWF4aW1pc2UgPSAxNDtcclxubGV0IFdpbmRvd1RvZ2dsZU1heGltaXNlID0gMTU7XHJcbmxldCBXaW5kb3dNaW5pbWlzZSA9IDE2O1xyXG5sZXQgV2luZG93VW5NaW5pbWlzZSA9IDE3O1xyXG5sZXQgV2luZG93UmVzdG9yZSA9IDE4O1xyXG5sZXQgV2luZG93U2hvdyA9IDE5O1xyXG5sZXQgV2luZG93Q2xvc2UgPSAyMDtcclxubGV0IFdpbmRvd1NldEJhY2tncm91bmRDb2xvdXIgPSAyMTtcclxubGV0IFdpbmRvd1NldFJlc2l6YWJsZSA9IDIyO1xyXG5sZXQgV2luZG93V2lkdGggPSAyMztcclxubGV0IFdpbmRvd0hlaWdodCA9IDI0O1xyXG5sZXQgV2luZG93Wm9vbUluID0gMjU7XHJcbmxldCBXaW5kb3dab29tT3V0ID0gMjY7XHJcbmxldCBXaW5kb3dab29tUmVzZXQgPSAyNztcclxubGV0IFdpbmRvd0dldFpvb21MZXZlbCA9IDI4O1xyXG5sZXQgV2luZG93U2V0Wm9vbUxldmVsID0gMjk7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbmV3V2luZG93KHdpbmRvd05hbWUpIHtcclxuICAgIGxldCBjYWxsID0gbmV3UnVudGltZUNhbGxlcldpdGhJRChvYmplY3ROYW1lcy5XaW5kb3csIHdpbmRvd05hbWUpO1xyXG4gICAgcmV0dXJuIHtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ2VudGVycyB0aGUgd2luZG93LlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIENlbnRlcjogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd0NlbnRlciksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFNldCB0aGUgd2luZG93IHRpdGxlLlxyXG4gICAgICAgICAqIEBwYXJhbSB0aXRsZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFNldFRpdGxlOiAodGl0bGUpID0+IHZvaWQgY2FsbChXaW5kb3dTZXRUaXRsZSwge3RpdGxlfSksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIE1ha2VzIHRoZSB3aW5kb3cgZnVsbHNjcmVlbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICBGdWxsc2NyZWVuOiAoKSA9PiB2b2lkIGNhbGwoV2luZG93RnVsbHNjcmVlbiksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFVuZnVsbHNjcmVlbiB0aGUgd2luZG93LlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFVuRnVsbHNjcmVlbjogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd1VuRnVsbHNjcmVlbiksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFNldCB0aGUgd2luZG93IHNpemUuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoIFRoZSB3aW5kb3cgd2lkdGhcclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IFRoZSB3aW5kb3cgaGVpZ2h0XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgU2V0U2l6ZTogKHdpZHRoLCBoZWlnaHQpID0+IGNhbGwoV2luZG93U2V0U2l6ZSwge3dpZHRoLGhlaWdodH0pLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXQgdGhlIHdpbmRvdyBzaXplLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtQcm9taXNlPFNpemU+fSBUaGUgd2luZG93IHNpemVcclxuICAgICAgICAgKi9cclxuICAgICAgICBTaXplOiAoKSA9PiB7IHJldHVybiBjYWxsKFdpbmRvd1NpemUpOyB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgdGhlIHdpbmRvdyBtYXhpbXVtIHNpemUuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFNldE1heFNpemU6ICh3aWR0aCwgaGVpZ2h0KSA9PiB2b2lkIGNhbGwoV2luZG93U2V0TWF4U2l6ZSwge3dpZHRoLGhlaWdodH0pLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgdGhlIHdpbmRvdyBtaW5pbXVtIHNpemUuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFNldE1pblNpemU6ICh3aWR0aCwgaGVpZ2h0KSA9PiB2b2lkIGNhbGwoV2luZG93U2V0TWluU2l6ZSwge3dpZHRoLGhlaWdodH0pLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgd2luZG93IHRvIGJlIGFsd2F5cyBvbiB0b3AuXHJcbiAgICAgICAgICogQHBhcmFtIHtib29sZWFufSBvblRvcCBXaGV0aGVyIHRoZSB3aW5kb3cgc2hvdWxkIGJlIGFsd2F5cyBvbiB0b3BcclxuICAgICAgICAgKi9cclxuICAgICAgICBTZXRBbHdheXNPblRvcDogKG9uVG9wKSA9PiB2b2lkIGNhbGwoV2luZG93U2V0QWx3YXlzT25Ub3AsIHthbHdheXNPblRvcDpvblRvcH0pLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgdGhlIHdpbmRvdyByZWxhdGl2ZSBwb3NpdGlvbi5cclxuICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0geFxyXG4gICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgU2V0UmVsYXRpdmVQb3NpdGlvbjogKHgsIHkpID0+IGNhbGwoV2luZG93U2V0UmVsYXRpdmVQb3NpdGlvbiwge3gseX0pLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXQgdGhlIHdpbmRvdyBwb3NpdGlvbi5cclxuICAgICAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxQb3NpdGlvbj59IFRoZSB3aW5kb3cgcG9zaXRpb25cclxuICAgICAgICAgKi9cclxuICAgICAgICBSZWxhdGl2ZVBvc2l0aW9uOiAoKSA9PiB7IHJldHVybiBjYWxsKFdpbmRvd1JlbGF0aXZlUG9zaXRpb24pOyB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXQgdGhlIHNjcmVlbiB0aGUgd2luZG93IGlzIG9uLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtQcm9taXNlPFNjcmVlbj59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgU2NyZWVuOiAoKSA9PiB7IHJldHVybiBjYWxsKFdpbmRvd1NjcmVlbik7IH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEhpZGUgdGhlIHdpbmRvd1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEhpZGU6ICgpID0+IHZvaWQgY2FsbChXaW5kb3dIaWRlKSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogTWF4aW1pc2UgdGhlIHdpbmRvd1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIE1heGltaXNlOiAoKSA9PiB2b2lkIGNhbGwoV2luZG93TWF4aW1pc2UpLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTaG93IHRoZSB3aW5kb3dcclxuICAgICAgICAgKi9cclxuICAgICAgICBTaG93OiAoKSA9PiB2b2lkIGNhbGwoV2luZG93U2hvdyksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENsb3NlIHRoZSB3aW5kb3dcclxuICAgICAgICAgKi9cclxuICAgICAgICBDbG9zZTogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd0Nsb3NlKSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVG9nZ2xlIHRoZSB3aW5kb3cgbWF4aW1pc2Ugc3RhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBUb2dnbGVNYXhpbWlzZTogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd1RvZ2dsZU1heGltaXNlKSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVW5tYXhpbWlzZSB0aGUgd2luZG93XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgVW5NYXhpbWlzZTogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd1VuTWF4aW1pc2UpLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBNaW5pbWlzZSB0aGUgd2luZG93XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgTWluaW1pc2U6ICgpID0+IHZvaWQgY2FsbChXaW5kb3dNaW5pbWlzZSksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFVubWluaW1pc2UgdGhlIHdpbmRvd1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFVuTWluaW1pc2U6ICgpID0+IHZvaWQgY2FsbChXaW5kb3dVbk1pbmltaXNlKSxcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmVzdG9yZSB0aGUgd2luZG93XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgUmVzdG9yZTogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd1Jlc3RvcmUpLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgdGhlIGJhY2tncm91bmQgY29sb3VyIG9mIHRoZSB3aW5kb3cuXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHIgLSBBIHZhbHVlIGJldHdlZW4gMCBhbmQgMjU1XHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGcgLSBBIHZhbHVlIGJldHdlZW4gMCBhbmQgMjU1XHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGIgLSBBIHZhbHVlIGJldHdlZW4gMCBhbmQgMjU1XHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGEgLSBBIHZhbHVlIGJldHdlZW4gMCBhbmQgMjU1XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgU2V0QmFja2dyb3VuZENvbG91cjogKHIsIGcsIGIsIGEpID0+IHZvaWQgY2FsbChXaW5kb3dTZXRCYWNrZ3JvdW5kQ29sb3VyLCB7ciwgZywgYiwgYX0pLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgd2hldGhlciB0aGUgd2luZG93IGNhbiBiZSByZXNpemVkIG9yIG5vdFxyXG4gICAgICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gcmVzaXphYmxlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgU2V0UmVzaXphYmxlOiAocmVzaXphYmxlKSA9PiB2b2lkIGNhbGwoV2luZG93U2V0UmVzaXphYmxlLCB7cmVzaXphYmxlfSksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEdldCB0aGUgd2luZG93IHdpZHRoXHJcbiAgICAgICAgICogQHJldHVybnMge1Byb21pc2U8bnVtYmVyPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBXaWR0aDogKCkgPT4geyByZXR1cm4gY2FsbChXaW5kb3dXaWR0aCk7IH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEdldCB0aGUgd2luZG93IGhlaWdodFxyXG4gICAgICAgICAqIEByZXR1cm5zIHtQcm9taXNlPG51bWJlcj59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgSGVpZ2h0OiAoKSA9PiB7IHJldHVybiBjYWxsKFdpbmRvd0hlaWdodCk7IH0sXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFpvb20gaW4gdGhlIHdpbmRvd1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFpvb21JbjogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd1pvb21JbiksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFpvb20gb3V0IHRoZSB3aW5kb3dcclxuICAgICAgICAgKi9cclxuICAgICAgICBab29tT3V0OiAoKSA9PiB2b2lkIGNhbGwoV2luZG93Wm9vbU91dCksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJlc2V0IHRoZSB3aW5kb3cgem9vbVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFpvb21SZXNldDogKCkgPT4gdm9pZCBjYWxsKFdpbmRvd1pvb21SZXNldCksXHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEdldCB0aGUgd2luZG93IHpvb21cclxuICAgICAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxudW1iZXI+fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEdldFpvb21MZXZlbDogKCkgPT4geyByZXR1cm4gY2FsbChXaW5kb3dHZXRab29tTGV2ZWwpOyB9LFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTZXQgdGhlIHdpbmRvdyB6b29tIGxldmVsXHJcbiAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IHpvb21MZXZlbFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFNldFpvb21MZXZlbDogKHpvb21MZXZlbCkgPT4gdm9pZCBjYWxsKFdpbmRvd1NldFpvb21MZXZlbCwge3pvb21MZXZlbH0pLFxyXG4gICAgfTtcclxufVxyXG4iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuLyoganNoaW50IGVzdmVyc2lvbjogOSAqL1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL2FwaS90eXBlc1wiKS5XYWlsc0V2ZW50fSBXYWlsc0V2ZW50XHJcbiAqL1xyXG5cclxuaW1wb3J0IHtuZXdSdW50aW1lQ2FsbGVyV2l0aElELCBvYmplY3ROYW1lc30gZnJvbSBcIi4vcnVudGltZVwiO1xyXG5cclxubGV0IGNhbGwgPSBuZXdSdW50aW1lQ2FsbGVyV2l0aElEKG9iamVjdE5hbWVzLkV2ZW50cyk7XHJcbmxldCBFdmVudEVtaXQgPSAwO1xyXG5cclxuLyoqXHJcbiAqIFRoZSBMaXN0ZW5lciBjbGFzcyBkZWZpbmVzIGEgbGlzdGVuZXIhIDotKVxyXG4gKlxyXG4gKiBAY2xhc3MgTGlzdGVuZXJcclxuICovXHJcbmNsYXNzIExpc3RlbmVyIHtcclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBMaXN0ZW5lci5cclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWVcclxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrXHJcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWF4Q2FsbGJhY2tzXHJcbiAgICAgKiBAbWVtYmVyb2YgTGlzdGVuZXJcclxuICAgICAqL1xyXG4gICAgY29uc3RydWN0b3IoZXZlbnROYW1lLCBjYWxsYmFjaywgbWF4Q2FsbGJhY2tzKSB7XHJcbiAgICAgICAgdGhpcy5ldmVudE5hbWUgPSBldmVudE5hbWU7XHJcbiAgICAgICAgLy8gRGVmYXVsdCBvZiAtMSBtZWFucyBpbmZpbml0ZVxyXG4gICAgICAgIHRoaXMubWF4Q2FsbGJhY2tzID0gbWF4Q2FsbGJhY2tzIHx8IC0xO1xyXG4gICAgICAgIC8vIENhbGxiYWNrIGludm9rZXMgdGhlIGNhbGxiYWNrIHdpdGggdGhlIGdpdmVuIGRhdGFcclxuICAgICAgICAvLyBSZXR1cm5zIHRydWUgaWYgdGhpcyBsaXN0ZW5lciBzaG91bGQgYmUgZGVzdHJveWVkXHJcbiAgICAgICAgdGhpcy5DYWxsYmFjayA9IChkYXRhKSA9PiB7XHJcbiAgICAgICAgICAgIGNhbGxiYWNrKGRhdGEpO1xyXG4gICAgICAgICAgICAvLyBJZiBtYXhDYWxsYmFja3MgaXMgaW5maW5pdGUsIHJldHVybiBmYWxzZSAoZG8gbm90IGRlc3Ryb3kpXHJcbiAgICAgICAgICAgIGlmICh0aGlzLm1heENhbGxiYWNrcyA9PT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBEZWNyZW1lbnQgbWF4Q2FsbGJhY2tzLiBSZXR1cm4gdHJ1ZSBpZiBub3cgMCwgb3RoZXJ3aXNlIGZhbHNlXHJcbiAgICAgICAgICAgIHRoaXMubWF4Q2FsbGJhY2tzIC09IDE7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1heENhbGxiYWNrcyA9PT0gMDtcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIFdhaWxzRXZlbnQgZGVmaW5lcyBhIGN1c3RvbSBldmVudC4gSXQgaXMgcGFzc2VkIHRvIGV2ZW50IGxpc3RlbmVycy5cclxuICpcclxuICogQGNsYXNzIFdhaWxzRXZlbnRcclxuICogQHByb3BlcnR5IHtzdHJpbmd9IG5hbWUgLSBOYW1lIG9mIHRoZSBldmVudFxyXG4gKiBAcHJvcGVydHkge2FueX0gZGF0YSAtIERhdGEgYXNzb2NpYXRlZCB3aXRoIHRoZSBldmVudFxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIFdhaWxzRXZlbnQge1xyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGFuIGluc3RhbmNlIG9mIFdhaWxzRXZlbnQuXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIE5hbWUgb2YgdGhlIGV2ZW50XHJcbiAgICAgKiBAcGFyYW0ge2FueT1udWxsfSBkYXRhIC0gRGF0YSBhc3NvY2lhdGVkIHdpdGggdGhlIGV2ZW50XHJcbiAgICAgKiBAbWVtYmVyb2YgV2FpbHNFdmVudFxyXG4gICAgICovXHJcbiAgICBjb25zdHJ1Y3RvcihuYW1lLCBkYXRhID0gbnVsbCkge1xyXG4gICAgICAgIHRoaXMubmFtZSA9IG5hbWU7XHJcbiAgICAgICAgdGhpcy5kYXRhID0gZGF0YTtcclxuICAgIH1cclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IGV2ZW50TGlzdGVuZXJzID0gbmV3IE1hcCgpO1xyXG5cclxuLyoqXHJcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBgbWF4Q2FsbGJhY2tzYCB0aW1lcyBiZWZvcmUgYmVpbmcgZGVzdHJveWVkXHJcbiAqXHJcbiAqIEBleHBvcnRcclxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxyXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFdhaWxzRXZlbnQpOiB2b2lkfSBjYWxsYmFja1xyXG4gKiBAcGFyYW0ge251bWJlcn0gbWF4Q2FsbGJhY2tzXHJcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gQSBmdW5jdGlvbiB0byBjYW5jZWwgdGhlIGxpc3RlbmVyXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gT25NdWx0aXBsZShldmVudE5hbWUsIGNhbGxiYWNrLCBtYXhDYWxsYmFja3MpIHtcclxuICAgIGxldCBsaXN0ZW5lcnMgPSBldmVudExpc3RlbmVycy5nZXQoZXZlbnROYW1lKSB8fCBbXTtcclxuICAgIGNvbnN0IHRoaXNMaXN0ZW5lciA9IG5ldyBMaXN0ZW5lcihldmVudE5hbWUsIGNhbGxiYWNrLCBtYXhDYWxsYmFja3MpO1xyXG4gICAgbGlzdGVuZXJzLnB1c2godGhpc0xpc3RlbmVyKTtcclxuICAgIGV2ZW50TGlzdGVuZXJzLnNldChldmVudE5hbWUsIGxpc3RlbmVycyk7XHJcbiAgICByZXR1cm4gKCkgPT4gbGlzdGVuZXJPZmYodGhpc0xpc3RlbmVyKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBldmVyeSB0aW1lIHRoZSBldmVudCBpcyBlbWl0dGVkXHJcbiAqXHJcbiAqIEBleHBvcnRcclxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxyXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFdhaWxzRXZlbnQpOiB2b2lkfSBjYWxsYmFja1xyXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IEEgZnVuY3Rpb24gdG8gY2FuY2VsIHRoZSBsaXN0ZW5lclxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIE9uKGV2ZW50TmFtZSwgY2FsbGJhY2spIHtcclxuICAgIHJldHVybiBPbk11bHRpcGxlKGV2ZW50TmFtZSwgY2FsbGJhY2ssIC0xKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBvbmNlIHRoZW4gZGVzdHJveWVkXHJcbiAqXHJcbiAqIEBleHBvcnRcclxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxyXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKFdhaWxzRXZlbnQpOiB2b2lkfSBjYWxsYmFja1xyXG4gQHJldHVybnMge2Z1bmN0aW9ufSBBIGZ1bmN0aW9uIHRvIGNhbmNlbCB0aGUgbGlzdGVuZXJcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBPbmNlKGV2ZW50TmFtZSwgY2FsbGJhY2spIHtcclxuICAgIHJldHVybiBPbk11bHRpcGxlKGV2ZW50TmFtZSwgY2FsbGJhY2ssIDEpO1xyXG59XHJcblxyXG4vKipcclxuICogbGlzdGVuZXJPZmYgdW5yZWdpc3RlcnMgYSBsaXN0ZW5lciBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgd2l0aCBPblxyXG4gKlxyXG4gKiBAcGFyYW0ge0xpc3RlbmVyfSBsaXN0ZW5lclxyXG4gKi9cclxuZnVuY3Rpb24gbGlzdGVuZXJPZmYobGlzdGVuZXIpIHtcclxuICAgIGNvbnN0IGV2ZW50TmFtZSA9IGxpc3RlbmVyLmV2ZW50TmFtZTtcclxuICAgIC8vIFJlbW92ZSBsb2NhbCBsaXN0ZW5lclxyXG4gICAgbGV0IGxpc3RlbmVycyA9IGV2ZW50TGlzdGVuZXJzLmdldChldmVudE5hbWUpLmZpbHRlcihsID0+IGwgIT09IGxpc3RlbmVyKTtcclxuICAgIGlmIChsaXN0ZW5lcnMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgZXZlbnRMaXN0ZW5lcnMuZGVsZXRlKGV2ZW50TmFtZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIGV2ZW50TGlzdGVuZXJzLnNldChldmVudE5hbWUsIGxpc3RlbmVycyk7XHJcbiAgICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBkaXNwYXRjaGVzIGFuIGV2ZW50IHRvIGFsbCBsaXN0ZW5lcnNcclxuICpcclxuICogQGV4cG9ydFxyXG4gKiBAcGFyYW0ge1dhaWxzRXZlbnR9IGV2ZW50XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZGlzcGF0Y2hXYWlsc0V2ZW50KGV2ZW50KSB7XHJcbiAgICBsZXQgbGlzdGVuZXJzID0gZXZlbnRMaXN0ZW5lcnMuZ2V0KGV2ZW50Lm5hbWUpO1xyXG4gICAgaWYgKGxpc3RlbmVycykge1xyXG4gICAgICAgIC8vIGl0ZXJhdGUgbGlzdGVuZXJzIGFuZCBjYWxsIGNhbGxiYWNrLiBJZiBjYWxsYmFjayByZXR1cm5zIHRydWUsIHJlbW92ZSBsaXN0ZW5lclxyXG4gICAgICAgIGxldCB0b1JlbW92ZSA9IFtdO1xyXG4gICAgICAgIGxpc3RlbmVycy5mb3JFYWNoKGxpc3RlbmVyID0+IHtcclxuICAgICAgICAgICAgbGV0IHJlbW92ZSA9IGxpc3RlbmVyLkNhbGxiYWNrKGV2ZW50KTtcclxuICAgICAgICAgICAgaWYgKHJlbW92ZSkge1xyXG4gICAgICAgICAgICAgICAgdG9SZW1vdmUucHVzaChsaXN0ZW5lcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyByZW1vdmUgbGlzdGVuZXJzXHJcbiAgICAgICAgaWYgKHRvUmVtb3ZlLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgbGlzdGVuZXJzID0gbGlzdGVuZXJzLmZpbHRlcihsID0+ICF0b1JlbW92ZS5pbmNsdWRlcyhsKSk7XHJcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lcnMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBldmVudExpc3RlbmVycy5kZWxldGUoZXZlbnQubmFtZSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBldmVudExpc3RlbmVycy5zZXQoZXZlbnQubmFtZSwgbGlzdGVuZXJzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIE9mZiB1bnJlZ2lzdGVycyBhIGxpc3RlbmVyIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCB3aXRoIE9uLFxyXG4gKiBvcHRpb25hbGx5IG11bHRpcGxlIGxpc3RlbmVycyBjYW4gYmUgdW5yZWdpc3RlcmVkIHZpYSBgYWRkaXRpb25hbEV2ZW50TmFtZXNgXHJcbiAqXHJcbiBbdjMgQ0hBTkdFXSBPZmYgb25seSB1bnJlZ2lzdGVycyBsaXN0ZW5lcnMgd2l0aGluIHRoZSBjdXJyZW50IHdpbmRvd1xyXG4gKlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lXHJcbiAqIEBwYXJhbSAgey4uLnN0cmluZ30gYWRkaXRpb25hbEV2ZW50TmFtZXNcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBPZmYoZXZlbnROYW1lLCAuLi5hZGRpdGlvbmFsRXZlbnROYW1lcykge1xyXG4gICAgbGV0IGV2ZW50c1RvUmVtb3ZlID0gW2V2ZW50TmFtZSwgLi4uYWRkaXRpb25hbEV2ZW50TmFtZXNdO1xyXG4gICAgZXZlbnRzVG9SZW1vdmUuZm9yRWFjaChldmVudE5hbWUgPT4ge1xyXG4gICAgICAgIGV2ZW50TGlzdGVuZXJzLmRlbGV0ZShldmVudE5hbWUpO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBPZmZBbGwgdW5yZWdpc3RlcnMgYWxsIGxpc3RlbmVyc1xyXG4gKiBbdjMgQ0hBTkdFXSBPZmZBbGwgb25seSB1bnJlZ2lzdGVycyBsaXN0ZW5lcnMgd2l0aGluIHRoZSBjdXJyZW50IHdpbmRvd1xyXG4gKlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIE9mZkFsbCgpIHtcclxuICAgIGV2ZW50TGlzdGVuZXJzLmNsZWFyKCk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBFbWl0IGFuIGV2ZW50XHJcbiAqIEBwYXJhbSB7V2FpbHNFdmVudH0gZXZlbnQgVGhlIGV2ZW50IHRvIGVtaXRcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBFbWl0KGV2ZW50KSB7XHJcbiAgICB2b2lkIGNhbGwoRXZlbnRFbWl0LCBldmVudCk7XHJcbn0iLCAiLypcclxuIF9cdCAgIF9fXHQgIF8gX19cclxufCB8XHQgLyAvX19fIF8oXykgL19fX19cclxufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xyXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcclxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXHJcblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cclxuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxyXG4qL1xyXG5cclxuLyoganNoaW50IGVzdmVyc2lvbjogOSAqL1xyXG5cclxuLyoqXHJcbiAqIEB0eXBlZGVmIHtpbXBvcnQoXCIuL2FwaS90eXBlc1wiKS5NZXNzYWdlRGlhbG9nT3B0aW9uc30gTWVzc2FnZURpYWxvZ09wdGlvbnNcclxuICogQHR5cGVkZWYge2ltcG9ydChcIi4vYXBpL3R5cGVzXCIpLk9wZW5EaWFsb2dPcHRpb25zfSBPcGVuRGlhbG9nT3B0aW9uc1xyXG4gKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi9hcGkvdHlwZXNcIikuU2F2ZURpYWxvZ09wdGlvbnN9IFNhdmVEaWFsb2dPcHRpb25zXHJcbiAqL1xyXG5cclxuaW1wb3J0IHtuZXdSdW50aW1lQ2FsbGVyV2l0aElELCBvYmplY3ROYW1lc30gZnJvbSBcIi4vcnVudGltZVwiO1xyXG5cclxuaW1wb3J0IHsgbmFub2lkIH0gZnJvbSAnbmFub2lkL25vbi1zZWN1cmUnO1xyXG5cclxubGV0IGNhbGwgPSBuZXdSdW50aW1lQ2FsbGVyV2l0aElEKG9iamVjdE5hbWVzLkRpYWxvZyk7XHJcblxyXG5sZXQgRGlhbG9nSW5mbyA9IDA7XHJcbmxldCBEaWFsb2dXYXJuaW5nID0gMTtcclxubGV0IERpYWxvZ0Vycm9yID0gMjtcclxubGV0IERpYWxvZ1F1ZXN0aW9uID0gMztcclxubGV0IERpYWxvZ09wZW5GaWxlID0gNDtcclxubGV0IERpYWxvZ1NhdmVGaWxlID0gNTtcclxuXHJcblxyXG5sZXQgZGlhbG9nUmVzcG9uc2VzID0gbmV3IE1hcCgpO1xyXG5cclxuZnVuY3Rpb24gZ2VuZXJhdGVJRCgpIHtcclxuICAgIGxldCByZXN1bHQ7XHJcbiAgICBkbyB7XHJcbiAgICAgICAgcmVzdWx0ID0gbmFub2lkKCk7XHJcbiAgICB9IHdoaWxlIChkaWFsb2dSZXNwb25zZXMuaGFzKHJlc3VsdCkpO1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGRpYWxvZ0NhbGxiYWNrKGlkLCBkYXRhLCBpc0pTT04pIHtcclxuICAgIGxldCBwID0gZGlhbG9nUmVzcG9uc2VzLmdldChpZCk7XHJcbiAgICBpZiAocCkge1xyXG4gICAgICAgIGlmIChpc0pTT04pIHtcclxuICAgICAgICAgICAgcC5yZXNvbHZlKEpTT04ucGFyc2UoZGF0YSkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHAucmVzb2x2ZShkYXRhKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZGlhbG9nUmVzcG9uc2VzLmRlbGV0ZShpZCk7XHJcbiAgICB9XHJcbn1cclxuZXhwb3J0IGZ1bmN0aW9uIGRpYWxvZ0Vycm9yQ2FsbGJhY2soaWQsIG1lc3NhZ2UpIHtcclxuICAgIGxldCBwID0gZGlhbG9nUmVzcG9uc2VzLmdldChpZCk7XHJcbiAgICBpZiAocCkge1xyXG4gICAgICAgIHAucmVqZWN0KG1lc3NhZ2UpO1xyXG4gICAgICAgIGRpYWxvZ1Jlc3BvbnNlcy5kZWxldGUoaWQpO1xyXG4gICAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBkaWFsb2codHlwZSwgb3B0aW9ucykge1xyXG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcclxuICAgICAgICBsZXQgaWQgPSBnZW5lcmF0ZUlEKCk7XHJcbiAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcbiAgICAgICAgb3B0aW9uc1tcImRpYWxvZy1pZFwiXSA9IGlkO1xyXG4gICAgICAgIGRpYWxvZ1Jlc3BvbnNlcy5zZXQoaWQsIHtyZXNvbHZlLCByZWplY3R9KTtcclxuICAgICAgICBjYWxsKHR5cGUsIG9wdGlvbnMpLmNhdGNoKChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgICByZWplY3QoZXJyb3IpO1xyXG4gICAgICAgICAgICBkaWFsb2dSZXNwb25zZXMuZGVsZXRlKGlkKTtcclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIFNob3dzIGFuIEluZm8gZGlhbG9nIHdpdGggdGhlIGdpdmVuIG9wdGlvbnMuXHJcbiAqIEBwYXJhbSB7TWVzc2FnZURpYWxvZ09wdGlvbnN9IG9wdGlvbnNcclxuICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nPn0gVGhlIGxhYmVsIG9mIHRoZSBidXR0b24gcHJlc3NlZFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIEluZm8ob3B0aW9ucykge1xyXG4gICAgcmV0dXJuIGRpYWxvZyhEaWFsb2dJbmZvLCBvcHRpb25zKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFNob3dzIGEgV2FybmluZyBkaWFsb2cgd2l0aCB0aGUgZ2l2ZW4gb3B0aW9ucy5cclxuICogQHBhcmFtIHtNZXNzYWdlRGlhbG9nT3B0aW9uc30gb3B0aW9uc1xyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fSBUaGUgbGFiZWwgb2YgdGhlIGJ1dHRvbiBwcmVzc2VkXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gV2FybmluZyhvcHRpb25zKSB7XHJcbiAgICByZXR1cm4gZGlhbG9nKERpYWxvZ1dhcm5pbmcsIG9wdGlvbnMpO1xyXG59XHJcblxyXG4vKipcclxuICogU2hvd3MgYW4gRXJyb3IgZGlhbG9nIHdpdGggdGhlIGdpdmVuIG9wdGlvbnMuXHJcbiAqIEBwYXJhbSB7TWVzc2FnZURpYWxvZ09wdGlvbnN9IG9wdGlvbnNcclxuICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nPn0gVGhlIGxhYmVsIG9mIHRoZSBidXR0b24gcHJlc3NlZFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIEVycm9yKG9wdGlvbnMpIHtcclxuICAgIHJldHVybiBkaWFsb2coRGlhbG9nRXJyb3IsIG9wdGlvbnMpO1xyXG59XHJcblxyXG4vKipcclxuICogU2hvd3MgYSBRdWVzdGlvbiBkaWFsb2cgd2l0aCB0aGUgZ2l2ZW4gb3B0aW9ucy5cclxuICogQHBhcmFtIHtNZXNzYWdlRGlhbG9nT3B0aW9uc30gb3B0aW9uc1xyXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmc+fSBUaGUgbGFiZWwgb2YgdGhlIGJ1dHRvbiBwcmVzc2VkXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gUXVlc3Rpb24ob3B0aW9ucykge1xyXG4gICAgcmV0dXJuIGRpYWxvZyhEaWFsb2dRdWVzdGlvbiwgb3B0aW9ucyk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBTaG93cyBhbiBPcGVuIGRpYWxvZyB3aXRoIHRoZSBnaXZlbiBvcHRpb25zLlxyXG4gKiBAcGFyYW0ge09wZW5EaWFsb2dPcHRpb25zfSBvcHRpb25zXHJcbiAqIEByZXR1cm5zIHtQcm9taXNlPHN0cmluZ1tdfHN0cmluZz59IFJldHVybnMgdGhlIHNlbGVjdGVkIGZpbGUgb3IgYW4gYXJyYXkgb2Ygc2VsZWN0ZWQgZmlsZXMgaWYgQWxsb3dzTXVsdGlwbGVTZWxlY3Rpb24gaXMgdHJ1ZS4gQSBibGFuayBzdHJpbmcgaXMgcmV0dXJuZWQgaWYgbm8gZmlsZSB3YXMgc2VsZWN0ZWQuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gT3BlbkZpbGUob3B0aW9ucykge1xyXG4gICAgcmV0dXJuIGRpYWxvZyhEaWFsb2dPcGVuRmlsZSwgb3B0aW9ucyk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBTaG93cyBhIFNhdmUgZGlhbG9nIHdpdGggdGhlIGdpdmVuIG9wdGlvbnMuXHJcbiAqIEBwYXJhbSB7U2F2ZURpYWxvZ09wdGlvbnN9IG9wdGlvbnNcclxuICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nPn0gUmV0dXJucyB0aGUgc2VsZWN0ZWQgZmlsZS4gQSBibGFuayBzdHJpbmcgaXMgcmV0dXJuZWQgaWYgbm8gZmlsZSB3YXMgc2VsZWN0ZWQuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gU2F2ZUZpbGUob3B0aW9ucykge1xyXG4gICAgcmV0dXJuIGRpYWxvZyhEaWFsb2dTYXZlRmlsZSwgb3B0aW9ucyk7XHJcbn1cclxuXHJcbiIsICJpbXBvcnQge25ld1J1bnRpbWVDYWxsZXJXaXRoSUQsIG9iamVjdE5hbWVzfSBmcm9tIFwiLi9ydW50aW1lXCI7XHJcblxyXG5sZXQgY2FsbCA9IG5ld1J1bnRpbWVDYWxsZXJXaXRoSUQob2JqZWN0TmFtZXMuQ29udGV4dE1lbnUpO1xyXG5cclxubGV0IENvbnRleHRNZW51T3BlbiA9IDA7XHJcblxyXG5mdW5jdGlvbiBvcGVuQ29udGV4dE1lbnUoaWQsIHgsIHksIGRhdGEpIHtcclxuICAgIHZvaWQgY2FsbChDb250ZXh0TWVudU9wZW4sIHtpZCwgeCwgeSwgZGF0YX0pO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gc2V0dXBDb250ZXh0TWVudXMoKSB7XHJcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignY29udGV4dG1lbnUnLCBjb250ZXh0TWVudUhhbmRsZXIpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjb250ZXh0TWVudUhhbmRsZXIoZXZlbnQpIHtcclxuICAgIC8vIENoZWNrIGZvciBjdXN0b20gY29udGV4dCBtZW51XHJcbiAgICBsZXQgZWxlbWVudCA9IGV2ZW50LnRhcmdldDtcclxuICAgIGxldCBjdXN0b21Db250ZXh0TWVudSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpLmdldFByb3BlcnR5VmFsdWUoXCItLWN1c3RvbS1jb250ZXh0bWVudVwiKTtcclxuICAgIGN1c3RvbUNvbnRleHRNZW51ID0gY3VzdG9tQ29udGV4dE1lbnUgPyBjdXN0b21Db250ZXh0TWVudS50cmltKCkgOiBcIlwiO1xyXG4gICAgaWYgKGN1c3RvbUNvbnRleHRNZW51KSB7XHJcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICBsZXQgY3VzdG9tQ29udGV4dE1lbnVEYXRhID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWxlbWVudCkuZ2V0UHJvcGVydHlWYWx1ZShcIi0tY3VzdG9tLWNvbnRleHRtZW51LWRhdGFcIik7XHJcbiAgICAgICAgb3BlbkNvbnRleHRNZW51KGN1c3RvbUNvbnRleHRNZW51LCBldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZLCBjdXN0b21Db250ZXh0TWVudURhdGEpO1xyXG4gICAgICAgIHJldHVyblxyXG4gICAgfVxyXG5cclxuICAgIHByb2Nlc3NEZWZhdWx0Q29udGV4dE1lbnUoZXZlbnQpO1xyXG59XHJcblxyXG5cclxuLypcclxuLS1kZWZhdWx0LWNvbnRleHRtZW51OiBhdXRvOyAoZGVmYXVsdCkgd2lsbCBzaG93IHRoZSBkZWZhdWx0IGNvbnRleHQgbWVudSBpZiBjb250ZW50RWRpdGFibGUgaXMgdHJ1ZSBPUiB0ZXh0IGhhcyBiZWVuIHNlbGVjdGVkIE9SIGVsZW1lbnQgaXMgaW5wdXQgb3IgdGV4dGFyZWFcclxuLS1kZWZhdWx0LWNvbnRleHRtZW51OiBzaG93OyB3aWxsIGFsd2F5cyBzaG93IHRoZSBkZWZhdWx0IGNvbnRleHQgbWVudVxyXG4tLWRlZmF1bHQtY29udGV4dG1lbnU6IGhpZGU7IHdpbGwgYWx3YXlzIGhpZGUgdGhlIGRlZmF1bHQgY29udGV4dCBtZW51XHJcblxyXG5UaGlzIHJ1bGUgaXMgaW5oZXJpdGVkIGxpa2Ugbm9ybWFsIENTUyBydWxlcywgc28gbmVzdGluZyB3b3JrcyBhcyBleHBlY3RlZFxyXG4qL1xyXG5mdW5jdGlvbiBwcm9jZXNzRGVmYXVsdENvbnRleHRNZW51KGV2ZW50KSB7XHJcbiAgICAvLyBEZWJ1ZyBidWlsZHMgYWx3YXlzIHNob3cgdGhlIG1lbnVcclxuICAgIGlmIChERUJVRykge1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBQcm9jZXNzIGRlZmF1bHQgY29udGV4dCBtZW51XHJcbiAgICBjb25zdCBlbGVtZW50ID0gZXZlbnQudGFyZ2V0O1xyXG4gICAgY29uc3QgY29tcHV0ZWRTdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xyXG4gICAgY29uc3QgZGVmYXVsdENvbnRleHRNZW51QWN0aW9uID0gY29tcHV0ZWRTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKFwiLS1kZWZhdWx0LWNvbnRleHRtZW51XCIpLnRyaW0oKTtcclxuICAgIHN3aXRjaCAoZGVmYXVsdENvbnRleHRNZW51QWN0aW9uKSB7XHJcbiAgICAgICAgY2FzZSBcInNob3dcIjpcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIGNhc2UgXCJoaWRlXCI6XHJcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAvLyBDaGVjayBpZiBjb250ZW50RWRpdGFibGUgaXMgdHJ1ZVxyXG4gICAgICAgICAgICBpZiAoZWxlbWVudC5pc0NvbnRlbnRFZGl0YWJsZSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBDaGVjayBpZiB0ZXh0IGhhcyBiZWVuIHNlbGVjdGVkXHJcbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcclxuICAgICAgICAgICAgY29uc3QgaGFzU2VsZWN0aW9uID0gKHNlbGVjdGlvbi50b1N0cmluZygpLmxlbmd0aCA+IDApXHJcbiAgICAgICAgICAgIGlmIChoYXNTZWxlY3Rpb24pIHtcclxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZWN0aW9uLnJhbmdlQ291bnQ7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoaSk7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVjdHMgPSByYW5nZS5nZXRDbGllbnRSZWN0cygpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgcmVjdHMubGVuZ3RoOyBqKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVjdCA9IHJlY3RzW2pdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChyZWN0LmxlZnQsIHJlY3QudG9wKSA9PT0gZWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHRhZ25hbWUgaXMgaW5wdXQgb3IgdGV4dGFyZWFcclxuICAgICAgICAgICAgaWYgKGVsZW1lbnQudGFnTmFtZSA9PT0gXCJJTlBVVFwiIHx8IGVsZW1lbnQudGFnTmFtZSA9PT0gXCJURVhUQVJFQVwiKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaGFzU2VsZWN0aW9uIHx8ICghZWxlbWVudC5yZWFkT25seSAmJiAhZWxlbWVudC5kaXNhYmxlZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIGhpZGUgZGVmYXVsdCBjb250ZXh0IG1lbnVcclxuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgIH1cclxufVxyXG4iLCAiXHJcbmltcG9ydCB7RW1pdCwgV2FpbHNFdmVudH0gZnJvbSBcIi4vZXZlbnRzXCI7XHJcbmltcG9ydCB7UXVlc3Rpb259IGZyb20gXCIuL2RpYWxvZ3NcIjtcclxuXHJcbmZ1bmN0aW9uIHNlbmRFdmVudChldmVudE5hbWUsIGRhdGE9bnVsbCkge1xyXG4gICAgbGV0IGV2ZW50ID0gbmV3IFdhaWxzRXZlbnQoZXZlbnROYW1lLCBkYXRhKTtcclxuICAgIEVtaXQoZXZlbnQpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRXTUxFdmVudExpc3RlbmVycygpIHtcclxuICAgIGNvbnN0IGVsZW1lbnRzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW3dtbC1ldmVudF0nKTtcclxuICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICBjb25zdCBldmVudFR5cGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLWV2ZW50Jyk7XHJcbiAgICAgICAgY29uc3QgY29uZmlybSA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd3bWwtY29uZmlybScpO1xyXG4gICAgICAgIGNvbnN0IHRyaWdnZXIgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLXRyaWdnZXInKSB8fCBcImNsaWNrXCI7XHJcblxyXG4gICAgICAgIGxldCBjYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKGNvbmZpcm0pIHtcclxuICAgICAgICAgICAgICAgIFF1ZXN0aW9uKHtUaXRsZTogXCJDb25maXJtXCIsIE1lc3NhZ2U6Y29uZmlybSwgRGV0YWNoZWQ6IGZhbHNlLCBCdXR0b25zOlt7TGFiZWw6XCJZZXNcIn0se0xhYmVsOlwiTm9cIiwgSXNEZWZhdWx0OnRydWV9XX0pLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT09IFwiTm9cIikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzZW5kRXZlbnQoZXZlbnRUeXBlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBzZW5kRXZlbnQoZXZlbnRUeXBlKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vIFJlbW92ZSBleGlzdGluZyBsaXN0ZW5lcnNcclxuXHJcbiAgICAgICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKHRyaWdnZXIsIGNhbGxiYWNrKTtcclxuXHJcbiAgICAgICAgLy8gQWRkIG5ldyBsaXN0ZW5lclxyXG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcih0cmlnZ2VyLCBjYWxsYmFjayk7XHJcbiAgICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gY2FsbFdpbmRvd01ldGhvZChtZXRob2QpIHtcclxuICAgIGlmICh3YWlscy5XaW5kb3dbbWV0aG9kXSA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgY29uc29sZS5sb2coXCJXaW5kb3cgbWV0aG9kIFwiICsgbWV0aG9kICsgXCIgbm90IGZvdW5kXCIpO1xyXG4gICAgfVxyXG4gICAgd2FpbHMuV2luZG93W21ldGhvZF0oKTtcclxufVxyXG5cclxuZnVuY3Rpb24gYWRkV01MV2luZG93TGlzdGVuZXJzKCkge1xyXG4gICAgY29uc3QgZWxlbWVudHMgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCdbd21sLXdpbmRvd10nKTtcclxuICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICBjb25zdCB3aW5kb3dNZXRob2QgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLXdpbmRvdycpO1xyXG4gICAgICAgIGNvbnN0IGNvbmZpcm0gPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLWNvbmZpcm0nKTtcclxuICAgICAgICBjb25zdCB0cmlnZ2VyID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3dtbC10cmlnZ2VyJykgfHwgXCJjbGlja1wiO1xyXG5cclxuICAgICAgICBsZXQgY2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChjb25maXJtKSB7XHJcbiAgICAgICAgICAgICAgICBRdWVzdGlvbih7VGl0bGU6IFwiQ29uZmlybVwiLCBNZXNzYWdlOmNvbmZpcm0sIEJ1dHRvbnM6W3tMYWJlbDpcIlllc1wifSx7TGFiZWw6XCJOb1wiLCBJc0RlZmF1bHQ6dHJ1ZX1dfSkudGhlbihmdW5jdGlvbiAocmVzdWx0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCAhPT0gXCJOb1wiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxXaW5kb3dNZXRob2Qod2luZG93TWV0aG9kKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjYWxsV2luZG93TWV0aG9kKHdpbmRvd01ldGhvZCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLy8gUmVtb3ZlIGV4aXN0aW5nIGxpc3RlbmVyc1xyXG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcih0cmlnZ2VyLCBjYWxsYmFjayk7XHJcblxyXG4gICAgICAgIC8vIEFkZCBuZXcgbGlzdGVuZXJcclxuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIodHJpZ2dlciwgY2FsbGJhY2spO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGFkZFdNTE9wZW5Ccm93c2VyTGlzdGVuZXIoKSB7XHJcbiAgICBjb25zdCBlbGVtZW50cyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ1t3bWwtb3BlbnVybF0nKTtcclxuICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICBjb25zdCB1cmwgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnd21sLW9wZW51cmwnKTtcclxuICAgICAgICBjb25zdCBjb25maXJtID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3dtbC1jb25maXJtJyk7XHJcbiAgICAgICAgY29uc3QgdHJpZ2dlciA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCd3bWwtdHJpZ2dlcicpIHx8IFwiY2xpY2tcIjtcclxuXHJcbiAgICAgICAgbGV0IGNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAoY29uZmlybSkge1xyXG4gICAgICAgICAgICAgICAgUXVlc3Rpb24oe1RpdGxlOiBcIkNvbmZpcm1cIiwgTWVzc2FnZTpjb25maXJtLCBCdXR0b25zOlt7TGFiZWw6XCJZZXNcIn0se0xhYmVsOlwiTm9cIiwgSXNEZWZhdWx0OnRydWV9XX0pLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT09IFwiTm9cIikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2b2lkIHdhaWxzLkJyb3dzZXIuT3BlblVSTCh1cmwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZvaWQgd2FpbHMuQnJvd3Nlci5PcGVuVVJMKHVybCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLy8gUmVtb3ZlIGV4aXN0aW5nIGxpc3RlbmVyc1xyXG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcih0cmlnZ2VyLCBjYWxsYmFjayk7XHJcblxyXG4gICAgICAgIC8vIEFkZCBuZXcgbGlzdGVuZXJcclxuICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIodHJpZ2dlciwgY2FsbGJhY2spO1xyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiByZWxvYWRXTUwoKSB7XHJcbiAgICBhZGRXTUxFdmVudExpc3RlbmVycygpO1xyXG4gICAgYWRkV01MV2luZG93TGlzdGVuZXJzKCk7XHJcbiAgICBhZGRXTUxPcGVuQnJvd3Nlckxpc3RlbmVyKCk7XHJcbn1cclxuIiwgIi8qXHJcbiBfXHQgICBfX1x0ICBfIF9fXHJcbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXHJcbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cclxufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXHJcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xyXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXHJcbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcclxuKi9cclxuXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcbi8vIGRlZmluZWQgaW4gdGhlIFRhc2tmaWxlXHJcbmV4cG9ydCBsZXQgaW52b2tlID0gZnVuY3Rpb24oaW5wdXQpIHtcclxuICAgIGlmKFdJTkRPV1MpIHtcclxuICAgICAgICBjaHJvbWUud2Vidmlldy5wb3N0TWVzc2FnZShpbnB1dCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIHdlYmtpdC5tZXNzYWdlSGFuZGxlcnMuZXh0ZXJuYWwucG9zdE1lc3NhZ2UoaW5wdXQpO1xyXG4gICAgfVxyXG59XHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcblxyXG5sZXQgZmxhZ3MgPSBuZXcgTWFwKCk7XHJcblxyXG5mdW5jdGlvbiBjb252ZXJ0VG9NYXAob2JqKSB7XHJcbiAgICBjb25zdCBtYXAgPSBuZXcgTWFwKCk7XHJcblxyXG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMob2JqKSkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIG1hcC5zZXQoa2V5LCBjb252ZXJ0VG9NYXAodmFsdWUpKTsgLy8gUmVjdXJzaXZlbHkgY29udmVydCBuZXN0ZWQgb2JqZWN0XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgbWFwLnNldChrZXksIHZhbHVlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG1hcDtcclxufVxyXG5cclxuZmV0Y2goXCIvd2FpbHMvZmxhZ3NcIikudGhlbigocmVzcG9uc2UpID0+IHtcclxuICAgIHJlc3BvbnNlLmpzb24oKS50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgICAgZmxhZ3MgPSBjb252ZXJ0VG9NYXAoZGF0YSk7XHJcbiAgICB9KTtcclxufSk7XHJcblxyXG5cclxuZnVuY3Rpb24gZ2V0VmFsdWVGcm9tTWFwKGtleVN0cmluZykge1xyXG4gICAgY29uc3Qga2V5cyA9IGtleVN0cmluZy5zcGxpdCgnLicpO1xyXG4gICAgbGV0IHZhbHVlID0gZmxhZ3M7XHJcblxyXG4gICAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xyXG4gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIE1hcCkge1xyXG4gICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLmdldChrZXkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHZhbHVlID0gdmFsdWVba2V5XTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdmFsdWU7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBHZXRGbGFnKGtleVN0cmluZykge1xyXG4gICAgcmV0dXJuIGdldFZhbHVlRnJvbU1hcChrZXlTdHJpbmcpO1xyXG59XHJcbiIsICIvKlxyXG4gX1x0ICAgX19cdCAgXyBfX1xyXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcblxyXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXHJcblxyXG5pbXBvcnQge2ludm9rZX0gZnJvbSBcIi4vaW52b2tlXCI7XHJcbmltcG9ydCB7R2V0RmxhZ30gZnJvbSBcIi4vZmxhZ3NcIjtcclxuXHJcbmxldCBzaG91bGREcmFnID0gZmFsc2U7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZHJhZ1Rlc3QoZSkge1xyXG4gICAgbGV0IHZhbCA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGUudGFyZ2V0KS5nZXRQcm9wZXJ0eVZhbHVlKFwiLS13ZWJraXQtYXBwLXJlZ2lvblwiKTtcclxuICAgIGlmICh2YWwpIHtcclxuICAgICAgICB2YWwgPSB2YWwudHJpbSgpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh2YWwgIT09IFwiZHJhZ1wiKSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIE9ubHkgcHJvY2VzcyB0aGUgcHJpbWFyeSBidXR0b25cclxuICAgIGlmIChlLmJ1dHRvbnMgIT09IDEpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGUuZGV0YWlsID09PSAxO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gc2V0dXBEcmFnKCkge1xyXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIG9uTW91c2VEb3duKTtcclxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBvbk1vdXNlTW92ZSk7XHJcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIG9uTW91c2VVcCk7XHJcbn1cclxuXHJcbmxldCByZXNpemVFZGdlID0gbnVsbDtcclxubGV0IHJlc2l6YWJsZSA9IGZhbHNlO1xyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIHNldFJlc2l6YWJsZSh2YWx1ZSkge1xyXG4gICAgcmVzaXphYmxlID0gdmFsdWU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHRlc3RSZXNpemUoZSkge1xyXG4gICAgaWYoIHJlc2l6ZUVkZ2UgKSB7XHJcbiAgICAgICAgaW52b2tlKFwicmVzaXplOlwiICsgcmVzaXplRWRnZSk7XHJcbiAgICAgICAgcmV0dXJuIHRydWVcclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZTtcclxufVxyXG5cclxuZnVuY3Rpb24gb25Nb3VzZURvd24oZSkge1xyXG5cclxuICAgIC8vIENoZWNrIGZvciByZXNpemluZyBvbiBXaW5kb3dzXHJcbiAgICBpZiggV0lORE9XUyApIHtcclxuICAgICAgICBpZiAodGVzdFJlc2l6ZSgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBpZiAoZHJhZ1Rlc3QoZSkpIHtcclxuICAgICAgICAvLyBJZ25vcmUgZHJhZyBvbiBzY3JvbGxiYXJzXHJcbiAgICAgICAgaWYgKGUub2Zmc2V0WCA+IGUudGFyZ2V0LmNsaWVudFdpZHRoIHx8IGUub2Zmc2V0WSA+IGUudGFyZ2V0LmNsaWVudEhlaWdodCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHNob3VsZERyYWcgPSB0cnVlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICBzaG91bGREcmFnID0gZmFsc2U7XHJcbiAgICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIG9uTW91c2VVcChlKSB7XHJcbiAgICBsZXQgbW91c2VQcmVzc2VkID0gZS5idXR0b25zICE9PSB1bmRlZmluZWQgPyBlLmJ1dHRvbnMgOiBlLndoaWNoO1xyXG4gICAgaWYgKG1vdXNlUHJlc3NlZCA+IDApIHtcclxuICAgICAgICBlbmREcmFnKCk7XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBlbmREcmFnKCkge1xyXG4gICAgZG9jdW1lbnQuYm9keS5zdHlsZS5jdXJzb3IgPSAnZGVmYXVsdCc7XHJcbiAgICBzaG91bGREcmFnID0gZmFsc2U7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNldFJlc2l6ZShjdXJzb3IpIHtcclxuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5jdXJzb3IgPSBjdXJzb3IgfHwgZGVmYXVsdEN1cnNvcjtcclxuICAgIHJlc2l6ZUVkZ2UgPSBjdXJzb3I7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIG9uTW91c2VNb3ZlKGUpIHtcclxuICAgIGlmIChzaG91bGREcmFnKSB7XHJcbiAgICAgICAgc2hvdWxkRHJhZyA9IGZhbHNlO1xyXG4gICAgICAgIGxldCBtb3VzZVByZXNzZWQgPSBlLmJ1dHRvbnMgIT09IHVuZGVmaW5lZCA/IGUuYnV0dG9ucyA6IGUud2hpY2g7XHJcbiAgICAgICAgaWYgKG1vdXNlUHJlc3NlZCA+IDApIHtcclxuICAgICAgICAgICAgaW52b2tlKFwiZHJhZ1wiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChXSU5ET1dTKSB7XHJcbiAgICAgICAgaWYgKHJlc2l6YWJsZSkge1xyXG4gICAgICAgICAgICBoYW5kbGVSZXNpemUoZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59XHJcblxyXG5sZXQgZGVmYXVsdEN1cnNvciA9IFwiYXV0b1wiO1xyXG5cclxuZnVuY3Rpb24gaGFuZGxlUmVzaXplKGUpIHtcclxuICAgIGxldCByZXNpemVIYW5kbGVIZWlnaHQgPSBHZXRGbGFnKFwic3lzdGVtLnJlc2l6ZUhhbmRsZUhlaWdodFwiKSB8fCA1O1xyXG4gICAgbGV0IHJlc2l6ZUhhbmRsZVdpZHRoID0gR2V0RmxhZyhcInN5c3RlbS5yZXNpemVIYW5kbGVXaWR0aFwiKSB8fCA1O1xyXG5cclxuICAgIC8vIEV4dHJhIHBpeGVscyBmb3IgdGhlIGNvcm5lciBhcmVhc1xyXG4gICAgbGV0IGNvcm5lckV4dHJhID0gR2V0RmxhZyhcInJlc2l6ZUNvcm5lckV4dHJhXCIpIHx8IDEwO1xyXG5cclxuICAgIGxldCByaWdodEJvcmRlciA9IHdpbmRvdy5vdXRlcldpZHRoIC0gZS5jbGllbnRYIDwgcmVzaXplSGFuZGxlV2lkdGg7XHJcbiAgICBsZXQgbGVmdEJvcmRlciA9IGUuY2xpZW50WCA8IHJlc2l6ZUhhbmRsZVdpZHRoO1xyXG4gICAgbGV0IHRvcEJvcmRlciA9IGUuY2xpZW50WSA8IHJlc2l6ZUhhbmRsZUhlaWdodDtcclxuICAgIGxldCBib3R0b21Cb3JkZXIgPSB3aW5kb3cub3V0ZXJIZWlnaHQgLSBlLmNsaWVudFkgPCByZXNpemVIYW5kbGVIZWlnaHQ7XHJcblxyXG4gICAgLy8gQWRqdXN0IGZvciBjb3JuZXJzXHJcbiAgICBsZXQgcmlnaHRDb3JuZXIgPSB3aW5kb3cub3V0ZXJXaWR0aCAtIGUuY2xpZW50WCA8IChyZXNpemVIYW5kbGVXaWR0aCArIGNvcm5lckV4dHJhKTtcclxuICAgIGxldCBsZWZ0Q29ybmVyID0gZS5jbGllbnRYIDwgKHJlc2l6ZUhhbmRsZVdpZHRoICsgY29ybmVyRXh0cmEpO1xyXG4gICAgbGV0IHRvcENvcm5lciA9IGUuY2xpZW50WSA8IChyZXNpemVIYW5kbGVIZWlnaHQgKyBjb3JuZXJFeHRyYSk7XHJcbiAgICBsZXQgYm90dG9tQ29ybmVyID0gd2luZG93Lm91dGVySGVpZ2h0IC0gZS5jbGllbnRZIDwgKHJlc2l6ZUhhbmRsZUhlaWdodCArIGNvcm5lckV4dHJhKTtcclxuXHJcbiAgICAvLyBJZiB3ZSBhcmVuJ3Qgb24gYW4gZWRnZSwgYnV0IHdlcmUsIHJlc2V0IHRoZSBjdXJzb3IgdG8gZGVmYXVsdFxyXG4gICAgaWYgKCFsZWZ0Qm9yZGVyICYmICFyaWdodEJvcmRlciAmJiAhdG9wQm9yZGVyICYmICFib3R0b21Cb3JkZXIgJiYgcmVzaXplRWRnZSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgc2V0UmVzaXplKCk7XHJcbiAgICB9XHJcbiAgICAvLyBBZGp1c3RlZCBmb3IgY29ybmVyIGFyZWFzXHJcbiAgICBlbHNlIGlmIChyaWdodENvcm5lciAmJiBib3R0b21Db3JuZXIpIHNldFJlc2l6ZShcInNlLXJlc2l6ZVwiKTtcclxuICAgIGVsc2UgaWYgKGxlZnRDb3JuZXIgJiYgYm90dG9tQ29ybmVyKSBzZXRSZXNpemUoXCJzdy1yZXNpemVcIik7XHJcbiAgICBlbHNlIGlmIChsZWZ0Q29ybmVyICYmIHRvcENvcm5lcikgc2V0UmVzaXplKFwibnctcmVzaXplXCIpO1xyXG4gICAgZWxzZSBpZiAodG9wQ29ybmVyICYmIHJpZ2h0Q29ybmVyKSBzZXRSZXNpemUoXCJuZS1yZXNpemVcIik7XHJcbiAgICBlbHNlIGlmIChsZWZ0Qm9yZGVyKSBzZXRSZXNpemUoXCJ3LXJlc2l6ZVwiKTtcclxuICAgIGVsc2UgaWYgKHRvcEJvcmRlcikgc2V0UmVzaXplKFwibi1yZXNpemVcIik7XHJcbiAgICBlbHNlIGlmIChib3R0b21Cb3JkZXIpIHNldFJlc2l6ZShcInMtcmVzaXplXCIpO1xyXG4gICAgZWxzZSBpZiAocmlnaHRCb3JkZXIpIHNldFJlc2l6ZShcImUtcmVzaXplXCIpO1xyXG59XHJcbiIsICIvKlxyXG4gXyAgICAgX18gICAgIF8gX19cclxufCB8ICAvIC9fX18gXyhfKSAvX19fX1xyXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXHJcbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxyXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cclxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xyXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XHJcbiovXHJcbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cclxuXHJcblxyXG5pbXBvcnQgKiBhcyBDbGlwYm9hcmQgZnJvbSAnLi9jbGlwYm9hcmQnO1xyXG5pbXBvcnQgKiBhcyBBcHBsaWNhdGlvbiBmcm9tICcuL2FwcGxpY2F0aW9uJztcclxuaW1wb3J0ICogYXMgU2NyZWVucyBmcm9tICcuL3NjcmVlbnMnO1xyXG5pbXBvcnQgKiBhcyBTeXN0ZW0gZnJvbSAnLi9zeXN0ZW0nO1xyXG5pbXBvcnQgKiBhcyBCcm93c2VyIGZyb20gJy4vYnJvd3Nlcic7XHJcbmltcG9ydCB7UGx1Z2luLCBDYWxsLCBjYWxsRXJyb3JDYWxsYmFjaywgY2FsbENhbGxiYWNrLCBDYWxsQnlJRCwgQ2FsbEJ5TmFtZX0gZnJvbSBcIi4vY2FsbHNcIjtcclxuaW1wb3J0IHtjbGllbnRJZH0gZnJvbSAnLi9ydW50aW1lJztcclxuaW1wb3J0IHtuZXdXaW5kb3d9IGZyb20gXCIuL3dpbmRvd1wiO1xyXG5pbXBvcnQge2Rpc3BhdGNoV2FpbHNFdmVudCwgRW1pdCwgT2ZmLCBPZmZBbGwsIE9uLCBPbmNlLCBPbk11bHRpcGxlfSBmcm9tIFwiLi9ldmVudHNcIjtcclxuaW1wb3J0IHtkaWFsb2dDYWxsYmFjaywgZGlhbG9nRXJyb3JDYWxsYmFjaywgRXJyb3IsIEluZm8sIE9wZW5GaWxlLCBRdWVzdGlvbiwgU2F2ZUZpbGUsIFdhcm5pbmcsfSBmcm9tIFwiLi9kaWFsb2dzXCI7XHJcbmltcG9ydCB7c2V0dXBDb250ZXh0TWVudXN9IGZyb20gXCIuL2NvbnRleHRtZW51XCI7XHJcbmltcG9ydCB7cmVsb2FkV01MfSBmcm9tIFwiLi93bWxcIjtcclxuaW1wb3J0IHtzZXR1cERyYWcsIGVuZERyYWcsIHNldFJlc2l6YWJsZX0gZnJvbSBcIi4vZHJhZ1wiO1xyXG5cclxud2luZG93LndhaWxzID0ge1xyXG4gICAgLi4ubmV3UnVudGltZShudWxsKSxcclxuICAgIENhcGFiaWxpdGllczoge30sXHJcbiAgICBjbGllbnRJZDogY2xpZW50SWQsXHJcbn07XHJcblxyXG5mZXRjaChcIi93YWlscy9jYXBhYmlsaXRpZXNcIikudGhlbigocmVzcG9uc2UpID0+IHtcclxuICAgIHJlc3BvbnNlLmpzb24oKS50aGVuKChkYXRhKSA9PiB7XHJcbiAgICAgICAgd2luZG93LndhaWxzLkNhcGFiaWxpdGllcyA9IGRhdGE7XHJcbiAgICB9KTtcclxufSk7XHJcblxyXG4vLyBJbnRlcm5hbCB3YWlscyBlbmRwb2ludHNcclxud2luZG93Ll93YWlscyA9IHtcclxuICAgIGRpYWxvZ0NhbGxiYWNrLFxyXG4gICAgZGlhbG9nRXJyb3JDYWxsYmFjayxcclxuICAgIGRpc3BhdGNoV2FpbHNFdmVudCxcclxuICAgIGNhbGxDYWxsYmFjayxcclxuICAgIGNhbGxFcnJvckNhbGxiYWNrLFxyXG4gICAgZW5kRHJhZyxcclxuICAgIHNldFJlc2l6YWJsZSxcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBuZXdSdW50aW1lKHdpbmRvd05hbWUpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICAgQ2xpcGJvYXJkOiB7XHJcbiAgICAgICAgICAgIC4uLkNsaXBib2FyZFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgQXBwbGljYXRpb246IHtcclxuICAgICAgICAgICAgLi4uQXBwbGljYXRpb24sXHJcbiAgICAgICAgICAgIEdldFdpbmRvd0J5TmFtZSh3aW5kb3dOYW1lKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3UnVudGltZSh3aW5kb3dOYW1lKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgU3lzdGVtLFxyXG4gICAgICAgIFNjcmVlbnMsXHJcbiAgICAgICAgQnJvd3NlcixcclxuICAgICAgICBDYWxsLFxyXG4gICAgICAgIENhbGxCeUlELFxyXG4gICAgICAgIENhbGxCeU5hbWUsXHJcbiAgICAgICAgUGx1Z2luLFxyXG4gICAgICAgIFdNTDoge1xyXG4gICAgICAgICAgICBSZWxvYWQ6IHJlbG9hZFdNTCxcclxuICAgICAgICB9LFxyXG4gICAgICAgIERpYWxvZzoge1xyXG4gICAgICAgICAgICBJbmZvLFxyXG4gICAgICAgICAgICBXYXJuaW5nLFxyXG4gICAgICAgICAgICBFcnJvcixcclxuICAgICAgICAgICAgUXVlc3Rpb24sXHJcbiAgICAgICAgICAgIE9wZW5GaWxlLFxyXG4gICAgICAgICAgICBTYXZlRmlsZSxcclxuICAgICAgICB9LFxyXG4gICAgICAgIEV2ZW50czoge1xyXG4gICAgICAgICAgICBFbWl0LFxyXG4gICAgICAgICAgICBPbixcclxuICAgICAgICAgICAgT25jZSxcclxuICAgICAgICAgICAgT25NdWx0aXBsZSxcclxuICAgICAgICAgICAgT2ZmLFxyXG4gICAgICAgICAgICBPZmZBbGwsXHJcbiAgICAgICAgfSxcclxuICAgICAgICBXaW5kb3c6IG5ld1dpbmRvdyh3aW5kb3dOYW1lKSxcclxuICAgIH07XHJcbn1cclxuXHJcbmlmIChERUJVRykge1xyXG4gICAgY29uc29sZS5sb2coXCJXYWlscyB2My4wLjAgRGVidWcgTW9kZSBFbmFibGVkXCIpO1xyXG59XHJcblxyXG5zZXR1cENvbnRleHRNZW51cygpO1xyXG5zZXR1cERyYWcoKTtcclxuXHJcbmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGZ1bmN0aW9uKCkge1xyXG4gICAg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VSxXQUFXO0FBQUEsYUFDOUMsYUFBYTtBQUFhLGdCQUFVLFdBQVc7QUFBQSxhQUMvQztBQUFZLGdCQUFVLFVBQVU7QUFBQSxhQUNoQztBQUFXLGdCQUFVLFVBQVU7QUFBQSxhQUMvQjtBQUFjLGdCQUFVLFVBQVU7QUFBQSxhQUNsQztBQUFhLGdCQUFVLFVBQVU7QUFBQSxFQUM5Qzs7O0FDcEhBLFNBQU8sUUFBUTtBQUFBLElBQ1gsR0FBRyxXQUFXLElBQUk7QUFBQSxJQUNsQixjQUFjLENBQUM7QUFBQSxJQUNmO0FBQUEsRUFDSjtBQUVBLFFBQU0scUJBQXFCLEVBQUUsS0FBSyxDQUFDLGFBQWE7QUFDNUMsYUFBUyxLQUFLLEVBQUUsS0FBSyxDQUFDLFNBQVM7QUFDM0IsYUFBTyxNQUFNLGVBQWU7QUFBQSxJQUNoQyxDQUFDO0FBQUEsRUFDTCxDQUFDO0FBR0QsU0FBTyxTQUFTO0FBQUEsSUFDWjtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLElBQ0E7QUFBQSxJQUNBO0FBQUEsSUFDQTtBQUFBLEVBQ0o7QUFFTyxXQUFTLFdBQVcsWUFBWTtBQUNuQyxXQUFPO0FBQUEsTUFDSCxXQUFXO0FBQUEsUUFDUCxHQUFHO0FBQUEsTUFDUDtBQUFBLE1BQ0EsYUFBYTtBQUFBLFFBQ1QsR0FBRztBQUFBLFFBQ0gsZ0JBQWdCQyxhQUFZO0FBQ3hCLGlCQUFPLFdBQVdBLFdBQVU7QUFBQSxRQUNoQztBQUFBLE1BQ0o7QUFBQSxNQUNBO0FBQUEsTUFDQTtBQUFBLE1BQ0E7QUFBQSxNQUNBO0FBQUEsTUFDQTtBQUFBLE1BQ0E7QUFBQSxNQUNBO0FBQUEsTUFDQSxLQUFLO0FBQUEsUUFDRCxRQUFRO0FBQUEsTUFDWjtBQUFBLE1BQ0EsUUFBUTtBQUFBLFFBQ0o7QUFBQSxRQUNBO0FBQUEsUUFDQSxPQUFBQztBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLE1BQ0o7QUFBQSxNQUNBLFFBQVE7QUFBQSxRQUNKO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxRQUNBO0FBQUEsUUFDQTtBQUFBLFFBQ0E7QUFBQSxNQUNKO0FBQUEsTUFDQSxRQUFRLFVBQVUsVUFBVTtBQUFBLElBQ2hDO0FBQUEsRUFDSjtBQUVBLE1BQUksTUFBTztBQUNQLFlBQVEsSUFBSSxpQ0FBaUM7QUFBQSxFQUNqRDtBQUVBLG9CQUFrQjtBQUNsQixZQUFVO0FBRVYsV0FBUyxpQkFBaUIsb0JBQW9CLFdBQVc7QUFDckQsY0FBVTtBQUFBLEVBQ2QsQ0FBQzsiLAogICJuYW1lcyI6IFsiY2FsbCIsICJjYWxsIiwgImNhbGwiLCAiY2FsbCIsICJjYWxsIiwgImNhbGwiLCAicmVzaXphYmxlIiwgImNhbGwiLCAiZXZlbnROYW1lIiwgImNhbGwiLCAiZ2VuZXJhdGVJRCIsICJFcnJvciIsICJjYWxsIiwgIndpbmRvd05hbWUiLCAiRXJyb3IiXQp9Cg== diff --git a/v3/internal/runtime/runtime_debug_linux.go b/v3/internal/runtime/runtime_debug_linux.go deleted file mode 100644 index c2940839204..00000000000 --- a/v3/internal/runtime/runtime_debug_linux.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build linux && !production - -package runtime - -import _ "embed" - -//go:embed runtime_debug_desktop_linux.js -var DesktopRuntime []byte diff --git a/v3/internal/runtime/runtime_debug_windows.go b/v3/internal/runtime/runtime_debug_windows.go deleted file mode 100644 index 09a3a91981f..00000000000 --- a/v3/internal/runtime/runtime_debug_windows.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build windows && !production - -package runtime - -import _ "embed" - -//go:embed runtime_debug_desktop_windows.js -var DesktopRuntime []byte diff --git a/v3/internal/runtime/runtime_production_darwin.go b/v3/internal/runtime/runtime_production_darwin.go deleted file mode 100644 index be2411d9ee9..00000000000 --- a/v3/internal/runtime/runtime_production_darwin.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build darwin && production - -package runtime - -import _ "embed" - -//go:embed runtime_production_desktop_darwin.js -var DesktopRuntime []byte diff --git a/v3/internal/runtime/runtime_production_desktop_darwin.js b/v3/internal/runtime/runtime_production_desktop_darwin.js deleted file mode 100644 index 5fdb99e378c..00000000000 --- a/v3/internal/runtime/runtime_production_desktop_darwin.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{var fe=Object.defineProperty;var g=(t,e)=>{for(var n in e)fe(t,n,{get:e[n],enumerable:!0})};var E={};g(E,{SetText:()=>xe,Text:()=>Ce});var me="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var m=(t=21)=>{let e="",n=t;for(;n--;)e+=me[Math.random()*64|0];return e};var pe=window.location.origin+"/wails/runtime",l={Call:0,Clipboard:1,Application:2,Events:3,ContextMenu:4,Dialog:5,Window:6,Screens:7,System:8,Browser:9},D=m();function we(t,e,n,o){let i=new URL(pe);i.searchParams.append("object",t),i.searchParams.append("method",e);let r={headers:{}};return n&&(r.headers["x-wails-window-name"]=n),o&&i.searchParams.append("args",JSON.stringify(o)),r.headers["x-wails-client-id"]=D,new Promise((u,S)=>{fetch(i,r).then(s=>{if(s.ok)return s.headers.get("Content-Type")&&s.headers.get("Content-Type").indexOf("application/json")!==-1?s.json():s.text();S(Error(s.statusText))}).then(s=>u(s)).catch(s=>S(s))})}function a(t,e){return function(n,o=null){return we(t,n,e,o)}}var B=a(l.Clipboard),ge=0,he=1;function xe(t){B(ge,{text:t})}function Ce(){return B(he)}var L={};g(L,{Hide:()=>ve,Quit:()=>We,Show:()=>be});var y=a(l.Application),R={Hide:0,Show:1,Quit:2};function ve(){y(R.Hide)}function be(){y(R.Show)}function We(){y(R.Quit)}var k={};g(k,{GetAll:()=>Ee,GetCurrent:()=>Re,GetPrimary:()=>ye});var O=a(l.Screens),Se=0,Me=1,De=2;function Ee(){return O(Se)}function ye(){return O(Me)}function Re(){return O(De)}var N={};g(N,{IsDarkMode:()=>ke});var Le=a(l.System),Oe=0;function ke(){return Le(Oe)}var z={};g(z,{OpenURL:()=>Ie});var Ne=a(l.Browser),ze=0;function Ie(t){Ne(ze,{url:t})}var Ae=a(l.Call),x=0,d=new Map;function Te(){let t;do t=m();while(d.has(t));return t}function j(t,e,n){let o=d.get(t);o&&(n?o.resolve(JSON.parse(e)):o.resolve(e),d.delete(t))}function H(t,e){let n=d.get(t);n&&(n.reject(e),d.delete(t))}function C(t,e){return new Promise((n,o)=>{let i=Te();e=e||{},e["call-id"]=i,d.set(i,{resolve:n,reject:o}),Ae(t,e).catch(r=>{o(r),d.delete(i)})})}function U(t){return C(x,t)}function F(t,...e){if(typeof t!="string"||t.split(".").length!==3)throw new Error("CallByName requires a string in the format 'package.struct.method'");let n=t.split(".");return C(x,{packageName:n[0],structName:n[1],methodName:n[2],args:e})}function G(t,...e){return C(x,{methodID:t,args:e})}function Z(t,e,...n){return C(x,{packageName:"wails-plugins",structName:t,methodName:e,args:n})}var Pe=0,Be=1,je=2,He=3,Ue=4,Fe=5,Ge=6,Ze=7,Ye=8,Qe=9,Xe=10,Ve=11,qe=12,Je=13,_e=14,Ke=15,$e=16,et=17,tt=18,nt=19,ot=20,it=21,rt=22,lt=23,at=24,st=25,ut=26,ct=27,dt=28,ft=29;function Y(t){let e=a(l.Window,t);return{Center:()=>void e(Pe),SetTitle:n=>void e(Be,{title:n}),Fullscreen:()=>void e(je),UnFullscreen:()=>void e(He),SetSize:(n,o)=>e(Ue,{width:n,height:o}),Size:()=>e(Fe),SetMaxSize:(n,o)=>void e(Ge,{width:n,height:o}),SetMinSize:(n,o)=>void e(Ze,{width:n,height:o}),SetAlwaysOnTop:n=>void e(Ye,{alwaysOnTop:n}),SetRelativePosition:(n,o)=>e(Qe,{x:n,y:o}),RelativePosition:()=>e(Xe),Screen:()=>e(Ve),Hide:()=>void e(qe),Maximise:()=>void e(Je),Show:()=>void e(nt),Close:()=>void e(ot),ToggleMaximise:()=>void e(Ke),UnMaximise:()=>void e(_e),Minimise:()=>void e($e),UnMinimise:()=>void e(et),Restore:()=>void e(tt),SetBackgroundColour:(n,o,i,r)=>void e(it,{r:n,g:o,b:i,a:r}),SetResizable:n=>void e(rt,{resizable:n}),Width:()=>e(lt),Height:()=>e(at),ZoomIn:()=>void e(st),ZoomOut:()=>void e(ut),ZoomReset:()=>void e(ct),GetZoomLevel:()=>e(dt),SetZoomLevel:n=>void e(ft,{zoomLevel:n})}}var mt=a(l.Events),pt=0,I=class{constructor(e,n,o){this.eventName=e,this.maxCallbacks=o||-1,this.Callback=i=>(n(i),this.maxCallbacks===-1?!1:(this.maxCallbacks-=1,this.maxCallbacks===0))}},v=class{constructor(e,n=null){this.name=e,this.data=n}},c=new Map;function b(t,e,n){let o=c.get(t)||[],i=new I(t,e,n);return o.push(i),c.set(t,o),()=>wt(i)}function Q(t,e){return b(t,e,-1)}function X(t,e){return b(t,e,1)}function wt(t){let e=t.eventName,n=c.get(e).filter(o=>o!==t);n.length===0?c.delete(e):c.set(e,n)}function V(t){let e=c.get(t.name);if(e){let n=[];e.forEach(o=>{o.Callback(t)&&n.push(o)}),n.length>0&&(e=e.filter(o=>!n.includes(o)),e.length===0?c.delete(t.name):c.set(t.name,e))}}function q(t,...e){[t,...e].forEach(o=>{c.delete(o)})}function J(){c.clear()}function W(t){mt(pt,t)}var gt=a(l.Dialog),ht=0,xt=1,Ct=2,vt=3,bt=4,Wt=5,f=new Map;function St(){let t;do t=m();while(f.has(t));return t}function _(t,e,n){let o=f.get(t);o&&(n?o.resolve(JSON.parse(e)):o.resolve(e),f.delete(t))}function K(t,e){let n=f.get(t);n&&(n.reject(e),f.delete(t))}function p(t,e){return new Promise((n,o)=>{let i=St();e=e||{},e["dialog-id"]=i,f.set(i,{resolve:n,reject:o}),gt(t,e).catch(r=>{o(r),f.delete(i)})})}function $(t){return p(ht,t)}function ee(t){return p(xt,t)}function te(t){return p(Ct,t)}function w(t){return p(vt,t)}function ne(t){return p(bt,t)}function oe(t){return p(Wt,t)}var Mt=a(l.ContextMenu),Dt=0;function Et(t,e,n,o){Mt(Dt,{id:t,x:e,y:n,data:o})}function ie(){window.addEventListener("contextmenu",yt)}function yt(t){let e=t.target,n=window.getComputedStyle(e).getPropertyValue("--custom-contextmenu");if(n=n?n.trim():"",n){t.preventDefault();let o=window.getComputedStyle(e).getPropertyValue("--custom-contextmenu-data");Et(n,t.clientX,t.clientY,o);return}Rt(t)}function Rt(t){let e=t.target;switch(window.getComputedStyle(e).getPropertyValue("--default-contextmenu").trim()){case"show":return;case"hide":t.preventDefault();return;default:if(e.isContentEditable)return;let i=window.getSelection(),r=i.toString().length>0;if(r)for(let u=0;u{t.json().then(e=>{Nt=se(e)})});var h=!1;function zt(t){let e=window.getComputedStyle(t.target).getPropertyValue("--webkit-app-region");return e&&(e=e.trim()),e!=="drag"||t.buttons!==1?!1:t.detail===1}function ue(){window.addEventListener("mousedown",At),window.addEventListener("mousemove",Pt),window.addEventListener("mouseup",Tt)}var It=!1;function ce(t){It=t}function At(t){if(zt(t)){if(t.offsetX>t.target.clientWidth||t.offsetY>t.target.clientHeight)return;h=!0}else h=!1}function Tt(t){(t.buttons!==void 0?t.buttons:t.which)>0&&T()}function T(){document.body.style.cursor="default",h=!1}function Pt(t){if(h){h=!1,(t.buttons!==void 0?t.buttons:t.which)>0&&ae("drag");return}}window.wails={...de(null),Capabilities:{},clientId:D};fetch("/wails/capabilities").then(t=>{t.json().then(e=>{window.wails.Capabilities=e})});window._wails={dialogCallback:_,dialogErrorCallback:K,dispatchWailsEvent:V,callCallback:j,callErrorCallback:H,endDrag:T,setResizable:ce};function de(t){return{Clipboard:{...E},Application:{...L,GetWindowByName(e){return de(e)}},System:N,Screens:k,Browser:z,Call:U,CallByID:G,CallByName:F,Plugin:Z,WML:{Reload:A},Dialog:{Info:$,Warning:ee,Error:te,Question:w,OpenFile:ne,SaveFile:oe},Events:{Emit:W,On:Q,Once:X,OnMultiple:b,Off:q,OffAll:J},Window:Y(t)}}ie();ue();document.addEventListener("DOMContentLoaded",function(){A()});})(); diff --git a/v3/internal/runtime/runtime_production_desktop_linux.js b/v3/internal/runtime/runtime_production_desktop_linux.js deleted file mode 100644 index 5fdb99e378c..00000000000 --- a/v3/internal/runtime/runtime_production_desktop_linux.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{var fe=Object.defineProperty;var g=(t,e)=>{for(var n in e)fe(t,n,{get:e[n],enumerable:!0})};var E={};g(E,{SetText:()=>xe,Text:()=>Ce});var me="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var m=(t=21)=>{let e="",n=t;for(;n--;)e+=me[Math.random()*64|0];return e};var pe=window.location.origin+"/wails/runtime",l={Call:0,Clipboard:1,Application:2,Events:3,ContextMenu:4,Dialog:5,Window:6,Screens:7,System:8,Browser:9},D=m();function we(t,e,n,o){let i=new URL(pe);i.searchParams.append("object",t),i.searchParams.append("method",e);let r={headers:{}};return n&&(r.headers["x-wails-window-name"]=n),o&&i.searchParams.append("args",JSON.stringify(o)),r.headers["x-wails-client-id"]=D,new Promise((u,S)=>{fetch(i,r).then(s=>{if(s.ok)return s.headers.get("Content-Type")&&s.headers.get("Content-Type").indexOf("application/json")!==-1?s.json():s.text();S(Error(s.statusText))}).then(s=>u(s)).catch(s=>S(s))})}function a(t,e){return function(n,o=null){return we(t,n,e,o)}}var B=a(l.Clipboard),ge=0,he=1;function xe(t){B(ge,{text:t})}function Ce(){return B(he)}var L={};g(L,{Hide:()=>ve,Quit:()=>We,Show:()=>be});var y=a(l.Application),R={Hide:0,Show:1,Quit:2};function ve(){y(R.Hide)}function be(){y(R.Show)}function We(){y(R.Quit)}var k={};g(k,{GetAll:()=>Ee,GetCurrent:()=>Re,GetPrimary:()=>ye});var O=a(l.Screens),Se=0,Me=1,De=2;function Ee(){return O(Se)}function ye(){return O(Me)}function Re(){return O(De)}var N={};g(N,{IsDarkMode:()=>ke});var Le=a(l.System),Oe=0;function ke(){return Le(Oe)}var z={};g(z,{OpenURL:()=>Ie});var Ne=a(l.Browser),ze=0;function Ie(t){Ne(ze,{url:t})}var Ae=a(l.Call),x=0,d=new Map;function Te(){let t;do t=m();while(d.has(t));return t}function j(t,e,n){let o=d.get(t);o&&(n?o.resolve(JSON.parse(e)):o.resolve(e),d.delete(t))}function H(t,e){let n=d.get(t);n&&(n.reject(e),d.delete(t))}function C(t,e){return new Promise((n,o)=>{let i=Te();e=e||{},e["call-id"]=i,d.set(i,{resolve:n,reject:o}),Ae(t,e).catch(r=>{o(r),d.delete(i)})})}function U(t){return C(x,t)}function F(t,...e){if(typeof t!="string"||t.split(".").length!==3)throw new Error("CallByName requires a string in the format 'package.struct.method'");let n=t.split(".");return C(x,{packageName:n[0],structName:n[1],methodName:n[2],args:e})}function G(t,...e){return C(x,{methodID:t,args:e})}function Z(t,e,...n){return C(x,{packageName:"wails-plugins",structName:t,methodName:e,args:n})}var Pe=0,Be=1,je=2,He=3,Ue=4,Fe=5,Ge=6,Ze=7,Ye=8,Qe=9,Xe=10,Ve=11,qe=12,Je=13,_e=14,Ke=15,$e=16,et=17,tt=18,nt=19,ot=20,it=21,rt=22,lt=23,at=24,st=25,ut=26,ct=27,dt=28,ft=29;function Y(t){let e=a(l.Window,t);return{Center:()=>void e(Pe),SetTitle:n=>void e(Be,{title:n}),Fullscreen:()=>void e(je),UnFullscreen:()=>void e(He),SetSize:(n,o)=>e(Ue,{width:n,height:o}),Size:()=>e(Fe),SetMaxSize:(n,o)=>void e(Ge,{width:n,height:o}),SetMinSize:(n,o)=>void e(Ze,{width:n,height:o}),SetAlwaysOnTop:n=>void e(Ye,{alwaysOnTop:n}),SetRelativePosition:(n,o)=>e(Qe,{x:n,y:o}),RelativePosition:()=>e(Xe),Screen:()=>e(Ve),Hide:()=>void e(qe),Maximise:()=>void e(Je),Show:()=>void e(nt),Close:()=>void e(ot),ToggleMaximise:()=>void e(Ke),UnMaximise:()=>void e(_e),Minimise:()=>void e($e),UnMinimise:()=>void e(et),Restore:()=>void e(tt),SetBackgroundColour:(n,o,i,r)=>void e(it,{r:n,g:o,b:i,a:r}),SetResizable:n=>void e(rt,{resizable:n}),Width:()=>e(lt),Height:()=>e(at),ZoomIn:()=>void e(st),ZoomOut:()=>void e(ut),ZoomReset:()=>void e(ct),GetZoomLevel:()=>e(dt),SetZoomLevel:n=>void e(ft,{zoomLevel:n})}}var mt=a(l.Events),pt=0,I=class{constructor(e,n,o){this.eventName=e,this.maxCallbacks=o||-1,this.Callback=i=>(n(i),this.maxCallbacks===-1?!1:(this.maxCallbacks-=1,this.maxCallbacks===0))}},v=class{constructor(e,n=null){this.name=e,this.data=n}},c=new Map;function b(t,e,n){let o=c.get(t)||[],i=new I(t,e,n);return o.push(i),c.set(t,o),()=>wt(i)}function Q(t,e){return b(t,e,-1)}function X(t,e){return b(t,e,1)}function wt(t){let e=t.eventName,n=c.get(e).filter(o=>o!==t);n.length===0?c.delete(e):c.set(e,n)}function V(t){let e=c.get(t.name);if(e){let n=[];e.forEach(o=>{o.Callback(t)&&n.push(o)}),n.length>0&&(e=e.filter(o=>!n.includes(o)),e.length===0?c.delete(t.name):c.set(t.name,e))}}function q(t,...e){[t,...e].forEach(o=>{c.delete(o)})}function J(){c.clear()}function W(t){mt(pt,t)}var gt=a(l.Dialog),ht=0,xt=1,Ct=2,vt=3,bt=4,Wt=5,f=new Map;function St(){let t;do t=m();while(f.has(t));return t}function _(t,e,n){let o=f.get(t);o&&(n?o.resolve(JSON.parse(e)):o.resolve(e),f.delete(t))}function K(t,e){let n=f.get(t);n&&(n.reject(e),f.delete(t))}function p(t,e){return new Promise((n,o)=>{let i=St();e=e||{},e["dialog-id"]=i,f.set(i,{resolve:n,reject:o}),gt(t,e).catch(r=>{o(r),f.delete(i)})})}function $(t){return p(ht,t)}function ee(t){return p(xt,t)}function te(t){return p(Ct,t)}function w(t){return p(vt,t)}function ne(t){return p(bt,t)}function oe(t){return p(Wt,t)}var Mt=a(l.ContextMenu),Dt=0;function Et(t,e,n,o){Mt(Dt,{id:t,x:e,y:n,data:o})}function ie(){window.addEventListener("contextmenu",yt)}function yt(t){let e=t.target,n=window.getComputedStyle(e).getPropertyValue("--custom-contextmenu");if(n=n?n.trim():"",n){t.preventDefault();let o=window.getComputedStyle(e).getPropertyValue("--custom-contextmenu-data");Et(n,t.clientX,t.clientY,o);return}Rt(t)}function Rt(t){let e=t.target;switch(window.getComputedStyle(e).getPropertyValue("--default-contextmenu").trim()){case"show":return;case"hide":t.preventDefault();return;default:if(e.isContentEditable)return;let i=window.getSelection(),r=i.toString().length>0;if(r)for(let u=0;u{t.json().then(e=>{Nt=se(e)})});var h=!1;function zt(t){let e=window.getComputedStyle(t.target).getPropertyValue("--webkit-app-region");return e&&(e=e.trim()),e!=="drag"||t.buttons!==1?!1:t.detail===1}function ue(){window.addEventListener("mousedown",At),window.addEventListener("mousemove",Pt),window.addEventListener("mouseup",Tt)}var It=!1;function ce(t){It=t}function At(t){if(zt(t)){if(t.offsetX>t.target.clientWidth||t.offsetY>t.target.clientHeight)return;h=!0}else h=!1}function Tt(t){(t.buttons!==void 0?t.buttons:t.which)>0&&T()}function T(){document.body.style.cursor="default",h=!1}function Pt(t){if(h){h=!1,(t.buttons!==void 0?t.buttons:t.which)>0&&ae("drag");return}}window.wails={...de(null),Capabilities:{},clientId:D};fetch("/wails/capabilities").then(t=>{t.json().then(e=>{window.wails.Capabilities=e})});window._wails={dialogCallback:_,dialogErrorCallback:K,dispatchWailsEvent:V,callCallback:j,callErrorCallback:H,endDrag:T,setResizable:ce};function de(t){return{Clipboard:{...E},Application:{...L,GetWindowByName(e){return de(e)}},System:N,Screens:k,Browser:z,Call:U,CallByID:G,CallByName:F,Plugin:Z,WML:{Reload:A},Dialog:{Info:$,Warning:ee,Error:te,Question:w,OpenFile:ne,SaveFile:oe},Events:{Emit:W,On:Q,Once:X,OnMultiple:b,Off:q,OffAll:J},Window:Y(t)}}ie();ue();document.addEventListener("DOMContentLoaded",function(){A()});})(); diff --git a/v3/internal/runtime/runtime_production_desktop_windows.js b/v3/internal/runtime/runtime_production_desktop_windows.js deleted file mode 100644 index f83dfd6739f..00000000000 --- a/v3/internal/runtime/runtime_production_desktop_windows.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{var xe=Object.defineProperty;var v=(e,t)=>{for(var n in t)xe(e,n,{get:t[n],enumerable:!0})};var O={};v(O,{SetText:()=>Me,Text:()=>De});var Ce="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";var g=(e=21)=>{let t="",n=e;for(;n--;)t+=Ce[Math.random()*64|0];return t};var ve=window.location.origin+"/wails/runtime",l={Call:0,Clipboard:1,Application:2,Events:3,ContextMenu:4,Dialog:5,Window:6,Screens:7,System:8,Browser:9},L=g();function We(e,t,n,o){let i=new URL(ve);i.searchParams.append("object",e),i.searchParams.append("method",t);let r={headers:{}};return n&&(r.headers["x-wails-window-name"]=n),o&&i.searchParams.append("args",JSON.stringify(o)),r.headers["x-wails-client-id"]=L,new Promise((u,p)=>{fetch(i,r).then(s=>{if(s.ok)return s.headers.get("Content-Type")&&s.headers.get("Content-Type").indexOf("application/json")!==-1?s.json():s.text();p(Error(s.statusText))}).then(s=>u(s)).catch(s=>p(s))})}function a(e,t){return function(n,o=null){return We(e,n,t,o)}}var G=a(l.Clipboard),be=0,Se=1;function Me(e){G(be,{text:e})}function De(){return G(Se)}var I={};v(I,{Hide:()=>Ee,Quit:()=>Re,Show:()=>ye});var k=a(l.Application),N={Hide:0,Show:1,Quit:2};function Ee(){k(N.Hide)}function ye(){k(N.Show)}function Re(){k(N.Quit)}var A={};v(A,{GetAll:()=>Ne,GetCurrent:()=>ze,GetPrimary:()=>Ie});var z=a(l.Screens),Le=0,Oe=1,ke=2;function Ne(){return z(Le)}function Ie(){return z(Oe)}function ze(){return z(ke)}var T={};v(T,{IsDarkMode:()=>Pe});var Ae=a(l.System),Te=0;function Pe(){return Ae(Te)}var P={};v(P,{OpenURL:()=>He});var Be=a(l.Browser),je=0;function He(e){Be(je,{url:e})}var Ue=a(l.Call),b=0,f=new Map;function Fe(){let e;do e=g();while(f.has(e));return e}function Z(e,t,n){let o=f.get(e);o&&(n?o.resolve(JSON.parse(t)):o.resolve(t),f.delete(e))}function Y(e,t){let n=f.get(e);n&&(n.reject(t),f.delete(e))}function S(e,t){return new Promise((n,o)=>{let i=Fe();t=t||{},t["call-id"]=i,f.set(i,{resolve:n,reject:o}),Ue(e,t).catch(r=>{o(r),f.delete(i)})})}function Q(e){return S(b,e)}function X(e,...t){if(typeof e!="string"||e.split(".").length!==3)throw new Error("CallByName requires a string in the format 'package.struct.method'");let n=e.split(".");return S(b,{packageName:n[0],structName:n[1],methodName:n[2],args:t})}function V(e,...t){return S(b,{methodID:e,args:t})}function q(e,t,...n){return S(b,{packageName:"wails-plugins",structName:e,methodName:t,args:n})}var Ge=0,Ze=1,Ye=2,Qe=3,Xe=4,Ve=5,qe=6,Je=7,_e=8,Ke=9,$e=10,et=11,tt=12,nt=13,ot=14,it=15,rt=16,lt=17,at=18,st=19,ut=20,ct=21,dt=22,ft=23,mt=24,pt=25,wt=26,gt=27,ht=28,xt=29;function J(e){let t=a(l.Window,e);return{Center:()=>void t(Ge),SetTitle:n=>void t(Ze,{title:n}),Fullscreen:()=>void t(Ye),UnFullscreen:()=>void t(Qe),SetSize:(n,o)=>t(Xe,{width:n,height:o}),Size:()=>t(Ve),SetMaxSize:(n,o)=>void t(qe,{width:n,height:o}),SetMinSize:(n,o)=>void t(Je,{width:n,height:o}),SetAlwaysOnTop:n=>void t(_e,{alwaysOnTop:n}),SetRelativePosition:(n,o)=>t(Ke,{x:n,y:o}),RelativePosition:()=>t($e),Screen:()=>t(et),Hide:()=>void t(tt),Maximise:()=>void t(nt),Show:()=>void t(st),Close:()=>void t(ut),ToggleMaximise:()=>void t(it),UnMaximise:()=>void t(ot),Minimise:()=>void t(rt),UnMinimise:()=>void t(lt),Restore:()=>void t(at),SetBackgroundColour:(n,o,i,r)=>void t(ct,{r:n,g:o,b:i,a:r}),SetResizable:n=>void t(dt,{resizable:n}),Width:()=>t(ft),Height:()=>t(mt),ZoomIn:()=>void t(pt),ZoomOut:()=>void t(wt),ZoomReset:()=>void t(gt),GetZoomLevel:()=>t(ht),SetZoomLevel:n=>void t(xt,{zoomLevel:n})}}var Ct=a(l.Events),vt=0,B=class{constructor(t,n,o){this.eventName=t,this.maxCallbacks=o||-1,this.Callback=i=>(n(i),this.maxCallbacks===-1?!1:(this.maxCallbacks-=1,this.maxCallbacks===0))}},M=class{constructor(t,n=null){this.name=t,this.data=n}},c=new Map;function D(e,t,n){let o=c.get(e)||[],i=new B(e,t,n);return o.push(i),c.set(e,o),()=>Wt(i)}function _(e,t){return D(e,t,-1)}function K(e,t){return D(e,t,1)}function Wt(e){let t=e.eventName,n=c.get(t).filter(o=>o!==e);n.length===0?c.delete(t):c.set(t,n)}function $(e){let t=c.get(e.name);if(t){let n=[];t.forEach(o=>{o.Callback(e)&&n.push(o)}),n.length>0&&(t=t.filter(o=>!n.includes(o)),t.length===0?c.delete(e.name):c.set(e.name,t))}}function ee(e,...t){[e,...t].forEach(o=>{c.delete(o)})}function te(){c.clear()}function E(e){Ct(vt,e)}var bt=a(l.Dialog),St=0,Mt=1,Dt=2,Et=3,yt=4,Rt=5,m=new Map;function Lt(){let e;do e=g();while(m.has(e));return e}function ne(e,t,n){let o=m.get(e);o&&(n?o.resolve(JSON.parse(t)):o.resolve(t),m.delete(e))}function oe(e,t){let n=m.get(e);n&&(n.reject(t),m.delete(e))}function h(e,t){return new Promise((n,o)=>{let i=Lt();t=t||{},t["dialog-id"]=i,m.set(i,{resolve:n,reject:o}),bt(e,t).catch(r=>{o(r),m.delete(i)})})}function ie(e){return h(St,e)}function re(e){return h(Mt,e)}function le(e){return h(Dt,e)}function x(e){return h(Et,e)}function ae(e){return h(yt,e)}function se(e){return h(Rt,e)}var Ot=a(l.ContextMenu),kt=0;function Nt(e,t,n,o){Ot(kt,{id:e,x:t,y:n,data:o})}function ue(){window.addEventListener("contextmenu",It)}function It(e){let t=e.target,n=window.getComputedStyle(t).getPropertyValue("--custom-contextmenu");if(n=n?n.trim():"",n){e.preventDefault();let o=window.getComputedStyle(t).getPropertyValue("--custom-contextmenu-data");Nt(n,e.clientX,e.clientY,o);return}zt(e)}function zt(e){let t=e.target;switch(window.getComputedStyle(t).getPropertyValue("--default-contextmenu").trim()){case"show":return;case"hide":e.preventDefault();return;default:if(t.isContentEditable)return;let i=window.getSelection(),r=i.toString().length>0;if(r)for(let u=0;u{e.json().then(t=>{fe=me(t)})});function Bt(e){let t=e.split("."),n=fe;for(let o of t)if(n instanceof Map?n=n.get(o):n=n[o],n===void 0)break;return n}function y(e){return Bt(e)}var W=!1;function jt(e){let t=window.getComputedStyle(e.target).getPropertyValue("--webkit-app-region");return t&&(t=t.trim()),t!=="drag"||e.buttons!==1?!1:e.detail===1}function pe(){window.addEventListener("mousedown",Ut),window.addEventListener("mousemove",Gt),window.addEventListener("mouseup",Ft)}var R=null,we=!1;function ge(e){we=e}function Ht(e){return R?(H("resize:"+R),!0):!1}function Ut(e){if(!Ht())if(jt(e)){if(e.offsetX>e.target.clientWidth||e.offsetY>e.target.clientHeight)return;W=!0}else W=!1}function Ft(e){(e.buttons!==void 0?e.buttons:e.which)>0&&U()}function U(){document.body.style.cursor="default",W=!1}function d(e){document.documentElement.style.cursor=e||Zt,R=e}function Gt(e){if(W){W=!1,(e.buttons!==void 0?e.buttons:e.which)>0&&H("drag");return}we&&Yt(e)}var Zt="auto";function Yt(e){let t=y("system.resizeHandleHeight")||5,n=y("system.resizeHandleWidth")||5,o=y("resizeCornerExtra")||10,i=window.outerWidth-e.clientX{e.json().then(t=>{window.wails.Capabilities=t})});window._wails={dialogCallback:ne,dialogErrorCallback:oe,dispatchWailsEvent:$,callCallback:Z,callErrorCallback:Y,endDrag:U,setResizable:ge};function he(e){return{Clipboard:{...O},Application:{...I,GetWindowByName(t){return he(t)}},System:T,Screens:A,Browser:P,Call:Q,CallByID:V,CallByName:X,Plugin:q,WML:{Reload:j},Dialog:{Info:ie,Warning:re,Error:le,Question:x,OpenFile:ae,SaveFile:se},Events:{Emit:E,On:_,Once:K,OnMultiple:D,Off:ee,OffAll:te},Window:J(e)}}ue();pe();document.addEventListener("DOMContentLoaded",function(){j()});})(); diff --git a/v3/internal/runtime/runtime_production_linux.go b/v3/internal/runtime/runtime_production_linux.go deleted file mode 100644 index d7c2bd1efdb..00000000000 --- a/v3/internal/runtime/runtime_production_linux.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build linux && production - -package runtime - -import _ "embed" - -//go:embed runtime_production_desktop_linux.js -var DesktopRuntime []byte diff --git a/v3/internal/runtime/runtime_production_windows.go b/v3/internal/runtime/runtime_production_windows.go deleted file mode 100644 index 8ab6d619947..00000000000 --- a/v3/internal/runtime/runtime_production_windows.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build windows && production - -package runtime - -import _ "embed" - -//go:embed runtime_production_desktop_windows.js -var DesktopRuntime []byte diff --git a/v3/pkg/application/application.go b/v3/pkg/application/application.go index 5fb7f96af36..afa61253180 100644 --- a/v3/pkg/application/application.go +++ b/v3/pkg/application/application.go @@ -825,3 +825,10 @@ func (a *App) BrowserOpenURL(url string) error { func (a *App) BrowserOpenFile(path string) error { return browser.OpenFile(path) } + +func (a *App) Environment() EnvironmentInfo { + return EnvironmentInfo{ + OS: runtime.GOOS, + Arch: runtime.GOARCH, + } +} diff --git a/v3/pkg/application/environment.go b/v3/pkg/application/environment.go new file mode 100644 index 00000000000..dbc7f3cedb1 --- /dev/null +++ b/v3/pkg/application/environment.go @@ -0,0 +1,6 @@ +package application + +type EnvironmentInfo struct { + OS string + Arch string +} diff --git a/v3/pkg/application/messageprocessor.go b/v3/pkg/application/messageprocessor.go index a7b4ee3c20c..1eef916c0e4 100644 --- a/v3/pkg/application/messageprocessor.go +++ b/v3/pkg/application/messageprocessor.go @@ -41,26 +41,26 @@ func (m *MessageProcessor) httpError(rw http.ResponseWriter, message string, arg rw.Write([]byte(fmt.Sprintf(message, args...))) } -func (m *MessageProcessor) getTargetWindow(r *http.Request) Window { +func (m *MessageProcessor) getTargetWindow(r *http.Request) (Window, string) { windowName := r.Header.Get(webViewRequestHeaderWindowName) if windowName != "" { - return globalApplication.GetWindowByName(windowName) + return globalApplication.GetWindowByName(windowName), windowName } windowID := r.Header.Get(webViewRequestHeaderWindowId) if windowID == "" { - return nil + return nil, windowID } wID, err := strconv.ParseUint(windowID, 10, 64) if err != nil { m.Error("Window ID '%s' not parsable: %s", windowID, err) - return nil + return nil, windowID } targetWindow := globalApplication.getWindowForID(uint(wID)) if targetWindow == nil { m.Error("Window ID %d not found", wID) - return nil + return nil, windowID } - return targetWindow + return targetWindow, windowID } func (m *MessageProcessor) HandleRuntimeCall(rw http.ResponseWriter, r *http.Request) { @@ -115,9 +115,9 @@ func (m *MessageProcessor) HandleRuntimeCallWithIDs(rw http.ResponseWriter, r *h } params := QueryParams(r.URL.Query()) - targetWindow := m.getTargetWindow(r) + targetWindow, nameOrID := m.getTargetWindow(r) if targetWindow == nil { - m.httpError(rw, "No valid window found") + m.httpError(rw, fmt.Sprintf("Window '%s' not found", nameOrID)) return } diff --git a/v3/pkg/application/messageprocessor_system.go b/v3/pkg/application/messageprocessor_system.go index fcd44a1a487..4930161eb8e 100644 --- a/v3/pkg/application/messageprocessor_system.go +++ b/v3/pkg/application/messageprocessor_system.go @@ -6,6 +6,7 @@ import ( const ( SystemIsDarkMode = 0 + Environment = 1 ) var systemMethodNames = map[int]string{ @@ -17,6 +18,8 @@ func (m *MessageProcessor) processSystemMethod(method int, rw http.ResponseWrite switch method { case SystemIsDarkMode: m.json(rw, globalApplication.IsDarkMode()) + case Environment: + m.json(rw, globalApplication.Environment()) default: m.httpError(rw, "Unknown system method: %d", method) } diff --git a/v3/pkg/application/webview_window.go b/v3/pkg/application/webview_window.go index a074b607a6d..8a2786db431 100644 --- a/v3/pkg/application/webview_window.go +++ b/v3/pkg/application/webview_window.go @@ -239,13 +239,13 @@ func (w *WebviewWindow) formatJS(f string, callID string, data string) string { func (w *WebviewWindow) CallError(callID string, result string) { if w.impl != nil { - w.impl.execJS(w.formatJS("_wails.callErrorCallback('%s', %s);", callID, result)) + w.impl.execJS(w.formatJS("_wails.callErrorHandler('%s', %s);", callID, result)) } } func (w *WebviewWindow) CallResponse(callID string, result string) { if w.impl != nil { - w.impl.execJS(w.formatJS("_wails.callCallback('%s', %s, true);", callID, result)) + w.impl.execJS(w.formatJS("_wails.callResultHandler('%s', %s, true);", callID, result)) } }