@mml-io/networked-dom-web-runner 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/index.js +14 -28
- package/build/index.js.map +2 -2
- package/package.json +4 -5
- package/src/IframeObservableDOMFactory.ts +21 -34
- package/src/RunnerIframe.ts +10 -8
- package/src/index.ts +0 -1
- package/src/message-types.ts +0 -30
package/build/index.js
CHANGED
|
@@ -29,7 +29,7 @@ module.exports = __toCommonJS(src_exports);
|
|
|
29
29
|
__reExport(src_exports, require("@mml-io/networked-dom-document"), module.exports);
|
|
30
30
|
|
|
31
31
|
// runner-iframe-js-text-namespace:/Users/marcuslongmuir/workspace/mml/packages/networked-dom-web-runner/networked-dom-web-runner-iframe/build/index.js
|
|
32
|
-
var build_default = 'var __defProp = Object.defineProperty;\nvar __defProps = Object.defineProperties;\nvar __getOwnPropDescs = Object.getOwnPropertyDescriptors;\nvar __getOwnPropSymbols = Object.getOwnPropertySymbols;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __propIsEnum = Object.prototype.propertyIsEnumerable;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __spreadValues = (a, b) => {\n for (var prop in b ||= {})\n if (__hasOwnProp.call(b, prop))\n __defNormalProp(a, prop, b[prop]);\n if (__getOwnPropSymbols)\n for (var prop of __getOwnPropSymbols(b)) {\n if (__propIsEnum.call(b, prop))\n __defNormalProp(a, prop, b[prop]);\n }\n return a;\n};\nvar __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));\n\n// ../../observable-dom/src/utils.ts\nfunction virtualDomElementToStatic(el) {\n return {\n nodeId: el.nodeId,\n tag: el.tag,\n attributes: el.attributes,\n childNodes: el.childNodes.map((child) => virtualDomElementToStatic(child)),\n textContent: el.textContent\n };\n}\n\n// ../../observable-dom/src/ObservableDom.ts\nvar ObservableDom = class {\n constructor(observableDOMParameters, callback, runnerFactory) {\n this.nodeToNodeId = /* @__PURE__ */ new Map();\n this.nodeIdToNode = /* @__PURE__ */ new Map();\n this.realElementToVirtualElement = /* @__PURE__ */ new Map();\n this.ignoreTextNodes = true;\n this.nextNodeId = 1;\n this.htmlPath = observableDOMParameters.htmlPath;\n this.ignoreTextNodes = observableDOMParameters.ignoreTextNodes;\n this.callback = callback;\n this.documentTimeIntervalTimer = setInterval(() => {\n this.callback({\n documentTime: this.getDocumentTime()\n });\n }, observableDOMParameters.pingIntervalMilliseconds || 5e3);\n this.domRunner = runnerFactory(\n observableDOMParameters.htmlPath,\n observableDOMParameters.htmlContents,\n observableDOMParameters.params,\n (domRunnerMessage) => {\n if (domRunnerMessage.loaded) {\n this.createVirtualDomElementWithChildren(\n this.domRunner.getDocument(),\n null\n );\n const snapshot = virtualDomElementToStatic(\n this.getVirtualDomElementForRealElementOrThrow(\n this.domRunner.getDocument()\n )\n );\n this.callback({\n snapshot,\n documentTime: this.getDocumentTime()\n });\n } else if (domRunnerMessage.mutationList) {\n this.processModificationList(domRunnerMessage.mutationList);\n } else if (domRunnerMessage.logMessage) {\n this.callback({\n logMessage: domRunnerMessage.logMessage,\n documentTime: this.getDocumentTime()\n });\n }\n }\n );\n }\n addIPCWebsocket(webSocket) {\n return this.domRunner.addIPCWebsocket(webSocket);\n }\n addConnectedUserId(connectionId) {\n this.domRunner.getWindow().dispatchEvent(\n new (this.domRunner.getWindow()).CustomEvent("connected", {\n detail: { connectionId }\n })\n );\n }\n removeConnectedUserId(connectionId) {\n this.domRunner.getWindow().dispatchEvent(\n new (this.domRunner.getWindow()).CustomEvent("disconnected", {\n detail: { connectionId }\n })\n );\n }\n processModificationList(mutationList) {\n const documentEl = this.domRunner.getDocument();\n const documentVirtualDomElement = this.realElementToVirtualElement.get(documentEl);\n if (!documentVirtualDomElement) {\n throw new Error(`document not created in processModificationList`);\n }\n if (mutationList.length > 1) {\n console.error(\n "More than one mutation record received. It is possible that intermediate states are incorrect."\n );\n }\n for (const mutation of mutationList) {\n if (this.isIgnoredElement(mutation.target)) {\n continue;\n }\n if (mutation.type === "attributes" && // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.isIgnoredAttribute(mutation.target, mutation.attributeName)) {\n continue;\n }\n this.addKnownNodesInMutation(mutation);\n const firstNonIgnoredPreviousSibling = mutation.previousSibling ? this.getFirstNonIgnoredPreviousSibling(mutation.previousSibling) : null;\n const targetElement = this.getVirtualDomElementForRealElementOrThrow(\n mutation.target\n );\n const addedNodes = [];\n for (const node of mutation.addedNodes) {\n if (this.isIgnoredElement(node)) {\n continue;\n }\n const virtualDomElement = this.getVirtualDomElementForRealElementOrThrow(\n node\n );\n addedNodes.push(virtualDomElementToStatic(virtualDomElement));\n }\n const removedNodeIds = [];\n for (const node of mutation.removedNodes) {\n if (this.isIgnoredElement(node)) {\n continue;\n }\n const virtualDomElement = this.getVirtualDomElementForRealElementOrThrow(\n node\n );\n removedNodeIds.push(virtualDomElement.nodeId);\n }\n const mutationRecord = {\n type: mutation.type,\n targetId: targetElement.nodeId,\n addedNodes,\n removedNodeIds,\n previousSiblingId: firstNonIgnoredPreviousSibling !== null ? this.getVirtualDomElementForRealElementOrThrow(firstNonIgnoredPreviousSibling).nodeId : null,\n attribute: mutation.attributeName ? {\n attributeName: mutation.attributeName,\n value: mutation.target.getAttribute(mutation.attributeName)\n } : null\n };\n this.callback({\n mutation: mutationRecord,\n documentTime: this.getDocumentTime()\n });\n this.removeKnownNodesInMutation(mutation);\n }\n }\n addKnownNodesInMutation(mutation) {\n const targetNode = mutation.target;\n const virtualDomElement = this.realElementToVirtualElement.get(targetNode);\n if (!virtualDomElement) {\n throw new Error(\n "Unknown node in addKnownNodesInMutation:" + targetNode + "," + mutation.type\n );\n }\n if (mutation.type === "childList") {\n let previousSibling = mutation.previousSibling;\n let index = 0;\n while (previousSibling && this.isIgnoredElement(previousSibling)) {\n previousSibling = previousSibling.previousSibling;\n }\n if (previousSibling) {\n const previousSiblingElement = this.realElementToVirtualElement.get(\n previousSibling\n );\n if (!previousSiblingElement) {\n throw new Error("Unknown previous sibling");\n }\n index = virtualDomElement.childNodes.indexOf(previousSiblingElement);\n if (index === -1) {\n throw new Error("Previous sibling is not currently a child of the parent element");\n }\n index += 1;\n }\n mutation.addedNodes.forEach((node) => {\n const asElementOrText = node;\n const childVirtualDomElement = this.createVirtualDomElementWithChildren(\n asElementOrText,\n virtualDomElement\n );\n if (childVirtualDomElement) {\n if (virtualDomElement.childNodes.indexOf(childVirtualDomElement) === -1) {\n virtualDomElement.childNodes.splice(index, 0, childVirtualDomElement);\n index++;\n }\n }\n });\n } else if (mutation.type === "attributes") {\n const attributeName = mutation.attributeName;\n if (this.isIgnoredAttribute(targetNode, attributeName)) {\n return;\n }\n const attributeValue = targetNode.getAttribute(attributeName);\n if (attributeValue === null) {\n delete virtualDomElement.attributes[attributeName];\n } else {\n virtualDomElement.attributes[attributeName] = attributeValue;\n }\n } else if (mutation.type === "characterData") {\n virtualDomElement.textContent = targetNode.textContent ? targetNode.textContent : void 0;\n }\n }\n removeKnownNodesInMutation(mutation) {\n const targetNode = mutation.target;\n const virtualDomElement = this.realElementToVirtualElement.get(targetNode);\n if (!virtualDomElement) {\n throw new Error("Unknown node in mutation list:" + targetNode + ", " + mutation.type);\n }\n if (mutation.type === "childList") {\n for (const node of mutation.removedNodes) {\n const asElementOrText = node;\n if (this.isIgnoredElement(asElementOrText)) {\n continue;\n }\n const childDomElement = this.realElementToVirtualElement.get(asElementOrText);\n if (!childDomElement) {\n console.warn(this.htmlPath, "Unknown node in removeKnownNodesInMutation");\n continue;\n } else {\n this.removeVirtualDomElement(childDomElement);\n const index = virtualDomElement.childNodes.indexOf(childDomElement);\n virtualDomElement.childNodes.splice(index, 1);\n }\n }\n return;\n }\n }\n removeVirtualDomElement(virtualDomElement) {\n this.nodeIdToNode.delete(virtualDomElement.nodeId);\n this.nodeToNodeId.delete(virtualDomElement);\n this.realElementToVirtualElement.delete(virtualDomElement.realElement);\n for (const child of virtualDomElement.childNodes) {\n this.removeVirtualDomElement(child);\n }\n }\n createVirtualDomElementWithChildren(node, parent) {\n const virtualElement = this.createVirtualDomElement(node, parent);\n if (!virtualElement) {\n return null;\n }\n if (node.childNodes) {\n for (let i = 0; i < node.childNodes.length; i++) {\n const child = node.childNodes[i];\n const childVirtualElement = this.createVirtualDomElementWithChildren(\n child,\n virtualElement\n );\n if (childVirtualElement) {\n virtualElement.childNodes.push(childVirtualElement);\n }\n }\n }\n return virtualElement;\n }\n createVirtualDomElement(node, parent) {\n if (this.isIgnoredElement(node)) {\n return null;\n }\n const existingValue = this.realElementToVirtualElement.get(node);\n if (existingValue !== void 0) {\n throw new Error("Node already has a virtual element: " + node.nodeName);\n }\n if (!node) {\n throw new Error("Cannot assign node id to null");\n }\n const attributes = {};\n if (node.attributes) {\n const asHTMLElement = node;\n for (const key of asHTMLElement.getAttributeNames()) {\n const value = asHTMLElement.getAttribute(key);\n if (value === null) {\n throw new Error("Null attribute value for key: " + key);\n }\n if (!this.isIgnoredAttribute(node, key)) {\n attributes[key] = value;\n }\n }\n }\n const nodeId = this.nextNodeId++;\n const virtualElement = {\n nodeId,\n tag: node.nodeName,\n attributes,\n childNodes: [],\n realElement: node,\n parent\n };\n if (node instanceof this.domRunner.getWindow().Text && node.textContent) {\n virtualElement.textContent = node.textContent;\n }\n this.nodeToNodeId.set(virtualElement, nodeId);\n this.nodeIdToNode.set(nodeId, virtualElement);\n this.realElementToVirtualElement.set(node, virtualElement);\n return virtualElement;\n }\n getFirstNonIgnoredPreviousSibling(node) {\n let currentNode = node;\n if (!this.isIgnoredElement(currentNode)) {\n return currentNode;\n }\n while (currentNode && currentNode.previousSibling) {\n currentNode = currentNode.previousSibling;\n if (!this.isIgnoredElement(currentNode)) {\n return currentNode;\n }\n }\n return null;\n }\n getVirtualDomElementForRealElementOrThrow(realElement) {\n const virtualElement = this.realElementToVirtualElement.get(realElement);\n if (!virtualElement) {\n throw new Error(`Virtual element not found for real element`);\n }\n return virtualElement;\n }\n isIgnoredElement(node) {\n if (this.ignoreTextNodes && node instanceof this.domRunner.getWindow().Text) {\n return true;\n } else if (node instanceof this.domRunner.getWindow().HTMLScriptElement) {\n return true;\n } else if (node instanceof this.domRunner.getWindow().Comment) {\n return true;\n }\n return false;\n }\n isIgnoredAttribute(node, attributeName) {\n return attributeName.startsWith("on");\n }\n dispatchRemoteEventFromConnectionId(connectionId, remoteEvent) {\n const domNode = this.nodeIdToNode.get(remoteEvent.nodeId);\n if (!domNode) {\n console.error("Unknown node ID in remote event: " + remoteEvent.nodeId);\n return;\n }\n if (domNode instanceof this.domRunner.getWindow().Text) {\n console.warn("Cannot dispatch remote event to text node");\n return;\n }\n this.domRunner.dispatchRemoteEventFromConnectionId(\n connectionId,\n domNode.realElement,\n remoteEvent\n );\n }\n dispose() {\n clearInterval(this.documentTimeIntervalTimer);\n this.domRunner.dispose();\n }\n getDocumentTime() {\n return this.domRunner.getDocumentTime();\n }\n};\n\n// src/WebBrowserDOMRunner.ts\nvar WebBrowserDOMRunnerFactory = (htmlPath, htmlContents, params, callback) => {\n return new WebBrowserDOMRunner(htmlPath, htmlContents, params, callback);\n};\nvar documentLoadTime = Date.now();\nvar WebBrowserDOMRunner = class {\n constructor(htmlPath, htmlContents, params, callback) {\n this.htmlPath = htmlPath;\n this.callback = callback;\n for (const level of ["error", "warn", "info", "log"]) {\n const defaultFn = window.console[level];\n window.console[level] = (...args2) => {\n callback({\n logMessage: {\n level,\n content: args2\n }\n });\n defaultFn(...args2);\n };\n }\n window.onerror = (message, source, line, column, error) => {\n callback({\n logMessage: {\n level: "system",\n content: [\n {\n message,\n type: error == null ? void 0 : error.name,\n line,\n column\n }\n ]\n }\n });\n return false;\n };\n let didSendLoad = false;\n this.mutationObserver = new window.MutationObserver((mutationList) => {\n if (!document) {\n return;\n }\n if (!didSendLoad) {\n throw new Error("MutationObserver called before load");\n }\n this.callback({\n mutationList\n });\n });\n window.params = params;\n const finishLoad = () => {\n if (didSendLoad) {\n throw new Error("finishLoad called twice");\n }\n didSendLoad = true;\n this.callback({\n loaded: true\n });\n this.mutationObserver.observe(window.document, {\n attributes: true,\n childList: true,\n subtree: true,\n characterData: true\n });\n };\n if (document.body) {\n setTimeout(finishLoad, 0);\n } else {\n window.addEventListener("DOMContentLoaded", finishLoad);\n }\n }\n addIPCWebsocket() {\n throw new Error("Not implemented.");\n }\n dispatchRemoteEventFromConnectionId(connectionId, realElement, remoteEvent) {\n const bubbles = remoteEvent.bubbles || false;\n const remoteEventObject = new CustomEvent(remoteEvent.name, {\n bubbles,\n detail: __spreadProps(__spreadValues({}, remoteEvent.params), { connectionId })\n });\n realElement.dispatchEvent(remoteEventObject);\n }\n dispose() {\n console.log("WebBrowserDOMRunner.dispose");\n }\n getDocument() {\n return document;\n }\n getDocumentTime() {\n if (document.timeline && document.timeline.currentTime) {\n return document.timeline.currentTime;\n }\n return Date.now() - documentLoadTime;\n }\n // TODO - resolve types (Window needs to expose classes such as CustomEvent as properties)\n getWindow() {\n return window;\n }\n};\n\n// src/IframeWebRunner.ts\nfunction setupIframeWebRunner(argsString) {\n const observableDOMParams = JSON.parse(atob(argsString));\n const sendMessageToHandler = (message) => {\n window.parent.postMessage(JSON.stringify(message), "*");\n };\n const observableDOM = new ObservableDom(\n __spreadProps(__spreadValues({}, observableDOMParams), {\n htmlContents: ""\n // This must be empty as the contents are assumed to be provided by the srcdoc\n }),\n (observableDomMessage) => {\n sendMessageToHandler({\n type: "dom",\n message: observableDomMessage\n });\n },\n WebBrowserDOMRunnerFactory\n );\n window.addEventListener("message", (e) => {\n const parsed = JSON.parse(e.data);\n if (parsed.type === "dispatchRemoteEventFromConnectionId") {\n observableDOM.dispatchRemoteEventFromConnectionId(parsed.connectionId, parsed.event);\n }\n });\n}\n\n// src/index.ts\nvar args = window.args;\nsetupIframeWebRunner(args);\n//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vb2JzZXJ2YWJsZS1kb20vc3JjL3V0aWxzLnRzIiwgIi4uLy4uLy4uL29ic2VydmFibGUtZG9tL3NyYy9PYnNlcnZhYmxlRG9tLnRzIiwgIi4uL3NyYy9XZWJCcm93c2VyRE9NUnVubmVyLnRzIiwgIi4uL3NyYy9JZnJhbWVXZWJSdW5uZXIudHMiLCAiLi4vc3JjL2luZGV4LnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQgeyBTdGF0aWNWaXJ0dWFsRG9tRWxlbWVudCB9IGZyb20gXCJAbW1sLWlvL29ic2VydmFibGUtZG9tLWNvbW1vblwiO1xuXG5pbXBvcnQgeyBMaXZlVmlydHVhbERvbUVsZW1lbnQgfSBmcm9tIFwiLi9PYnNlcnZhYmxlRG9tXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiB2aXJ0dWFsRG9tRWxlbWVudFRvU3RhdGljKGVsOiBMaXZlVmlydHVhbERvbUVsZW1lbnQpOiBTdGF0aWNWaXJ0dWFsRG9tRWxlbWVudCB7XG4gIHJldHVybiB7XG4gICAgbm9kZUlkOiBlbC5ub2RlSWQsXG4gICAgdGFnOiBlbC50YWcsXG4gICAgYXR0cmlidXRlczogZWwuYXR0cmlidXRlcyxcbiAgICBjaGlsZE5vZGVzOiBlbC5jaGlsZE5vZGVzLm1hcCgoY2hpbGQpID0+IHZpcnR1YWxEb21FbGVtZW50VG9TdGF0aWMoY2hpbGQpKSxcbiAgICB0ZXh0Q29udGVudDogZWwudGV4dENvbnRlbnQsXG4gIH07XG59XG4iLCAiaW1wb3J0IHtcbiAgTG9nTWVzc2FnZSxcbiAgT2JzZXJ2YWJsZURvbUludGVyZmFjZSxcbiAgT2JzZXJ2YWJsZURvbU1lc3NhZ2UsXG4gIE9ic2VydmFibGVET01QYXJhbWV0ZXJzLFxuICBSZW1vdGVFdmVudCxcbiAgU3RhdGljVmlydHVhbERvbUVsZW1lbnQsXG4gIFN0YXRpY1ZpcnR1YWxEb21NdXRhdGlvbklkc1JlY29yZCxcbn0gZnJvbSBcIkBtbWwtaW8vb2JzZXJ2YWJsZS1kb20tY29tbW9uXCI7XG5cbmltcG9ydCB7IHZpcnR1YWxEb21FbGVtZW50VG9TdGF0aWMgfSBmcm9tIFwiLi91dGlsc1wiO1xuXG5leHBvcnQgdHlwZSBET01SdW5uZXJNZXNzYWdlID0ge1xuICBsb2FkZWQ/OiBib29sZWFuO1xuICBtdXRhdGlvbkxpc3Q/OiBBcnJheTxNdXRhdGlvblJlY29yZD47XG4gIGxvZ01lc3NhZ2U/OiBMb2dNZXNzYWdlO1xufTtcblxuZXhwb3J0IHR5cGUgRE9NUnVubmVySW50ZXJmYWNlID0ge1xuICBnZXREb2N1bWVudCgpOiBEb2N1bWVudDtcbiAgZ2V0V2luZG93KCk6IFdpbmRvdyAmIHtcbiAgICBDdXN0b21FdmVudDogdHlwZW9mIEN1c3RvbUV2ZW50O1xuICAgIFRleHQ6IHR5cGVvZiBUZXh0O1xuICAgIEhUTUxTY3JpcHRFbGVtZW50OiB0eXBlb2YgSFRNTFNjcmlwdEVsZW1lbnQ7XG4gICAgQ29tbWVudDogdHlwZW9mIENvbW1lbnQ7XG4gIH07IC8vIFRPRE8gLSBEZWZpbmUgdGhpcyB3aXRob3V0IHVzaW5nIEpTRE9NIHR5cGVzXG4gIGFkZElQQ1dlYnNvY2tldCh3ZWJTb2NrZXQ6IFdlYlNvY2tldCk6IHZvaWQ7XG4gIGRpc3BhdGNoUmVtb3RlRXZlbnRGcm9tQ29ubmVjdGlvbklkKFxuICAgIGNvbm5lY3Rpb25JZDogbnVtYmVyLFxuICAgIHJlYWxFbGVtZW50OiBFbGVtZW50LFxuICAgIHJlbW90ZUV2ZW50OiBSZW1vdGVFdmVudCxcbiAgKTogdm9pZDtcbiAgZGlzcG9zZSgpOiB2b2lkO1xuICBnZXREb2N1bWVudFRpbWUoKTogbnVtYmVyO1xufTtcblxuZXhwb3J0IHR5cGUgRE9NUnVubmVyRmFjdG9yeSA9IChcbiAgaHRtbFBhdGg6IHN0cmluZyxcbiAgaHRtbENvbnRlbnRzOiBzdHJpbmcsXG4gIHBhcmFtczogb2JqZWN0LFxuICBjYWxsYmFjazogKGRvbVJ1bm5lck1lc3NhZ2U6IERPTVJ1bm5lck1lc3NhZ2UpID0+IHZvaWQsXG4pID0+IERPTVJ1bm5lckludGVyZmFjZTtcblxuZXhwb3J0IHR5cGUgTGl2ZVZpcnR1YWxEb21FbGVtZW50ID0gT21pdDxTdGF0aWNWaXJ0dWFsRG9tRWxlbWVudCwgXCJjaGlsZE5vZGVzXCI+ICYge1xuICByZWFsRWxlbWVudDogRWxlbWVudCB8IFRleHQ7XG4gIGNoaWxkTm9kZXM6IEFycmF5PExpdmVWaXJ0dWFsRG9tRWxlbWVudD47XG4gIHBhcmVudDogTGl2ZVZpcnR1YWxEb21FbGVtZW50IHwgbnVsbDtcbn07XG5cbmV4cG9ydCBjbGFzcyBPYnNlcnZhYmxlRG9tIGltcGxlbWVudHMgT2JzZXJ2YWJsZURvbUludGVyZmFjZSB7XG4gIHByaXZhdGUgbm9kZVRvTm9kZUlkID0gbmV3IE1hcDxMaXZlVmlydHVhbERvbUVsZW1lbnQsIG51bWJlcj4oKTtcbiAgcHJpdmF0ZSBub2RlSWRUb05vZGUgPSBuZXcgTWFwPG51bWJlciwgTGl2ZVZpcnR1YWxEb21FbGVtZW50PigpO1xuICBwcml2YXRlIHJlYWxFbGVtZW50VG9WaXJ0dWFsRWxlbWVudCA9IG5ldyBNYXA8RWxlbWVudCB8IFRleHQsIExpdmVWaXJ0dWFsRG9tRWxlbWVudD4oKTtcbiAgcHJpdmF0ZSBpZ25vcmVUZXh0Tm9kZXMgPSB0cnVlO1xuICBwcml2YXRlIGNhbGxiYWNrOiAobWVzc2FnZTogT2JzZXJ2YWJsZURvbU1lc3NhZ2UpID0+IHZvaWQ7XG4gIHByaXZhdGUgbmV4dE5vZGVJZCA9IDE7XG4gIHByaXZhdGUgaHRtbFBhdGg6IHN0cmluZztcbiAgcHJpdmF0ZSBkb21SdW5uZXI6IERPTVJ1bm5lckludGVyZmFjZTtcblxuICBwcml2YXRlIGRvY3VtZW50VGltZUludGVydmFsVGltZXI6IE5vZGVKUy5UaW1lcjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBvYnNlcnZhYmxlRE9NUGFyYW1ldGVyczogT2JzZXJ2YWJsZURPTVBhcmFtZXRlcnMsXG4gICAgY2FsbGJhY2s6IChtZXNzYWdlOiBPYnNlcnZhYmxlRG9tTWVzc2FnZSkgPT4gdm9pZCxcbiAgICBydW5uZXJGYWN0b3J5OiBET01SdW5uZXJGYWN0b3J5LFxuICApIHtcbiAgICB0aGlzLmh0bWxQYXRoID0gb2JzZXJ2YWJsZURPTVBhcmFtZXRlcnMuaHRtbFBhdGg7XG4gICAgdGhpcy5pZ25vcmVUZXh0Tm9kZXMgPSBvYnNlcnZhYmxlRE9NUGFyYW1ldGVycy5pZ25vcmVUZXh0Tm9kZXM7XG4gICAgdGhpcy5jYWxsYmFjayA9IGNhbGxiYWNrO1xuXG4gICAgdGhpcy5kb2N1bWVudFRpbWVJbnRlcnZhbFRpbWVyID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgdGhpcy5jYWxsYmFjayh7XG4gICAgICAgIGRvY3VtZW50VGltZTogdGhpcy5nZXREb2N1bWVudFRpbWUoKSxcbiAgICAgIH0pO1xuICAgIH0sIG9ic2VydmFibGVET01QYXJhbWV0ZXJzLnBpbmdJbnRlcnZhbE1pbGxpc2Vjb25kcyB8fCA1MDAwKTtcblxuICAgIHRoaXMuZG9tUnVubmVyID0gcnVubmVyRmFjdG9yeShcbiAgICAgIG9ic2VydmFibGVET01QYXJhbWV0ZXJzLmh0bWxQYXRoLFxuICAgICAgb2JzZXJ2YWJsZURPTVBhcmFtZXRlcnMuaHRtbENvbnRlbnRzLFxuICAgICAgb2JzZXJ2YWJsZURPTVBhcmFtZXRlcnMucGFyYW1zLFxuICAgICAgKGRvbVJ1bm5lck1lc3NhZ2U6IERPTVJ1bm5lck1lc3NhZ2UpID0+IHtcbiAgICAgICAgaWYgKGRvbVJ1bm5lck1lc3NhZ2UubG9hZGVkKSB7XG4gICAgICAgICAgdGhpcy5jcmVhdGVWaXJ0dWFsRG9tRWxlbWVudFdpdGhDaGlsZHJlbihcbiAgICAgICAgICAgIHRoaXMuZG9tUnVubmVyLmdldERvY3VtZW50KCkgYXMgdW5rbm93biBhcyBFbGVtZW50LFxuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgY29uc3Qgc25hcHNob3QgPSB2aXJ0dWFsRG9tRWxlbWVudFRvU3RhdGljKFxuICAgICAgICAgICAgdGhpcy5nZXRWaXJ0dWFsRG9tRWxlbWVudEZvclJlYWxFbGVtZW50T3JUaHJvdyhcbiAgICAgICAgICAgICAgdGhpcy5kb21SdW5uZXIuZ2V0RG9jdW1lbnQoKSBhcyB1bmtub3duIGFzIEVsZW1lbnQsXG4gICAgICAgICAgICApLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICB0aGlzLmNhbGxiYWNrKHtcbiAgICAgICAgICAgIHNuYXBzaG90LFxuICAgICAgICAgICAgZG9jdW1lbnRUaW1lOiB0aGlzLmdldERvY3VtZW50VGltZSgpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGRvbVJ1bm5lck1lc3NhZ2UubXV0YXRpb25MaXN0KSB7XG4gICAgICAgICAgdGhpcy5wcm9jZXNzTW9kaWZpY2F0aW9uTGlzdChkb21SdW5uZXJNZXNzYWdlLm11dGF0aW9uTGlzdCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZG9tUnVubmVyTWVzc2FnZS5sb2dNZXNzYWdlKSB7XG4gICAgICAgICAgdGhpcy5jYWxsYmFjayh7XG4gICAgICAgICAgICBsb2dNZXNzYWdlOiBkb21SdW5uZXJNZXNzYWdlLmxvZ01lc3NhZ2UsXG4gICAgICAgICAgICBkb2N1bWVudFRpbWU6IHRoaXMuZ2V0RG9jdW1lbnRUaW1lKCksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRJUENXZWJzb2NrZXQod2ViU29ja2V0OiBXZWJTb2NrZXQpIHtcbiAgICByZXR1cm4gdGhpcy5kb21SdW5uZXIuYWRkSVBDV2Vic29ja2V0KHdlYlNvY2tldCk7XG4gIH1cblxuICBwdWJsaWMgYWRkQ29ubmVjdGVkVXNlcklkKGNvbm5lY3Rpb25JZDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5kb21SdW5uZXIuZ2V0V2luZG93KCkuZGlzcGF0Y2hFdmVudChcbiAgICAgIG5ldyAodGhpcy5kb21SdW5uZXIuZ2V0V2luZG93KCkuQ3VzdG9tRXZlbnQpKFwiY29ubmVjdGVkXCIsIHtcbiAgICAgICAgZGV0YWlsOiB7IGNvbm5lY3Rpb25JZCB9LFxuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyByZW1vdmVDb25uZWN0ZWRVc2VySWQoY29ubmVjdGlvbklkOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmRvbVJ1bm5lci5nZXRXaW5kb3coKS5kaXNwYXRjaEV2ZW50KFxuICAgICAgbmV3ICh0aGlzLmRvbVJ1bm5lci5nZXRXaW5kb3coKS5DdXN0b21FdmVudCkoXCJkaXNjb25uZWN0ZWRcIiwge1xuICAgICAgICBkZXRhaWw6IHsgY29ubmVjdGlvbklkIH0sXG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9jZXNzTW9kaWZpY2F0aW9uTGlzdChtdXRhdGlvbkxpc3Q6IEFycmF5PE11dGF0aW9uUmVjb3JkPik6IHZvaWQge1xuICAgIGNvbnN0IGRvY3VtZW50RWwgPSB0aGlzLmRvbVJ1bm5lci5nZXREb2N1bWVudCgpIGFzIHVua25vd24gYXMgRWxlbWVudDtcbiAgICBjb25zdCBkb2N1bWVudFZpcnR1YWxEb21FbGVtZW50ID0gdGhpcy5yZWFsRWxlbWVudFRvVmlydHVhbEVsZW1lbnQuZ2V0KGRvY3VtZW50RWwpO1xuICAgIGlmICghZG9jdW1lbnRWaXJ0dWFsRG9tRWxlbWVudCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBkb2N1bWVudCBub3QgY3JlYXRlZCBpbiBwcm9jZXNzTW9kaWZpY2F0aW9uTGlzdGApO1xuICAgIH1cblxuICAgIGlmIChtdXRhdGlvbkxpc3QubGVuZ3RoID4gMSkge1xuICAgICAgLy8gVE9ETyAtIHdhbGsgYmFjayB0aHJvdWdoIHRoZSByZWNvcmRzIHRvIGRlcml2ZSB0aGUgaW50ZXJtZWRpYXRlIHN0YXRlcyAoZS5nLiBpZiBhbiBhdHRyaWJ1dGUgaXMgbGF0ZXIgYWRkZWQgdG9cbiAgICAgIC8vICBhbiBlbGVtZW50IGNyZWF0ZWQgaW4gYW4gZWFybGllciByZWNvcmQgdGhlbiBpdCBzaG91bGQgbm90IGhhdmUgdGhhdCBhdHRyaWJ1dGUgd2hlbiB0aGUgZWxlbWVudCBpcyBhZGRlZC5cbiAgICAgIC8vICBUaGlzIGlzIGltcG9ydGFudCBhcyBpbmNvcnJlY3QgYXR0cmlidXRlIHNldHMgY2FuIGFmZmVjdCB2aXNpYmlsaXR5IGFuZCBleHBlY3RlZCBjbGllbnQgcGVyZm9ybWFuY2UuXG4gICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICBcIk1vcmUgdGhhbiBvbmUgbXV0YXRpb24gcmVjb3JkIHJlY2VpdmVkLiBJdCBpcyBwb3NzaWJsZSB0aGF0IGludGVybWVkaWF0ZSBzdGF0ZXMgYXJlIGluY29ycmVjdC5cIixcbiAgICAgICk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBtdXRhdGlvbiBvZiBtdXRhdGlvbkxpc3QpIHtcbiAgICAgIGlmICh0aGlzLmlzSWdub3JlZEVsZW1lbnQobXV0YXRpb24udGFyZ2V0IGFzIEVsZW1lbnQgfCBUZXh0KSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBtdXRhdGlvbi50eXBlID09PSBcImF0dHJpYnV0ZXNcIiAmJlxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICB0aGlzLmlzSWdub3JlZEF0dHJpYnV0ZShtdXRhdGlvbi50YXJnZXQgYXMgRWxlbWVudCB8IFRleHQsIG11dGF0aW9uLmF0dHJpYnV0ZU5hbWUhKVxuICAgICAgKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmFkZEtub3duTm9kZXNJbk11dGF0aW9uKG11dGF0aW9uKTtcblxuICAgICAgLy8gQ29udmVydCB0aGUgXCJyZWFsXCIgRE9NIE11dGF0aW9uUmVjb3JkIGludG8gYSBcInZpcnR1YWxcIiBET00gTXV0YXRpb25SZWNvcmQgdGhhdCByZWZlcmVuY2VzIHRoZSBWaXJ0dWFsRE9NRWxlbWVudHNcbiAgICAgIC8vIFRoaXMgaXMgZG9uZSBzbyB0aGF0IHRoZSBzYW1lIHByb2Nlc3MgZm9yIGhhbmRsaW5nIG11dGF0aW9ucyBjYW4gYmUgdXNlZCBmb3IgYm90aCBjaGFuZ2VzIHRvIGEgbGl2ZSBET00gYW5kIGFsc29cbiAgICAgIC8vIHRvIGRpZmZzIGJldHdlZW4gRE9NIHNuYXBzaG90cyB3aGVuIHJlbG9hZGluZ1xuICAgICAgY29uc3QgZmlyc3ROb25JZ25vcmVkUHJldmlvdXNTaWJsaW5nID0gbXV0YXRpb24ucHJldmlvdXNTaWJsaW5nXG4gICAgICAgID8gdGhpcy5nZXRGaXJzdE5vbklnbm9yZWRQcmV2aW91c1NpYmxpbmcobXV0YXRpb24ucHJldmlvdXNTaWJsaW5nIGFzIEVsZW1lbnQgfCBUZXh0KVxuICAgICAgICA6IG51bGw7XG4gICAgICBjb25zdCB0YXJnZXRFbGVtZW50ID0gdGhpcy5nZXRWaXJ0dWFsRG9tRWxlbWVudEZvclJlYWxFbGVtZW50T3JUaHJvdyhcbiAgICAgICAgbXV0YXRpb24udGFyZ2V0IGFzIEVsZW1lbnQgfCBUZXh0LFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGFkZGVkTm9kZXM6IEFycmF5PFN0YXRpY1ZpcnR1YWxEb21FbGVtZW50PiA9IFtdO1xuICAgICAgZm9yIChjb25zdCBub2RlIG9mIG11dGF0aW9uLmFkZGVkTm9kZXMpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNJZ25vcmVkRWxlbWVudChub2RlIGFzIEVsZW1lbnQgfCBUZXh0KSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZpcnR1YWxEb21FbGVtZW50ID0gdGhpcy5nZXRWaXJ0dWFsRG9tRWxlbWVudEZvclJlYWxFbGVtZW50T3JUaHJvdyhcbiAgICAgICAgICBub2RlIGFzIEVsZW1lbnQgfCBUZXh0LFxuICAgICAgICApO1xuICAgICAgICBhZGRlZE5vZGVzLnB1c2godmlydHVhbERvbUVsZW1lbnRUb1N0YXRpYyh2aXJ0dWFsRG9tRWxlbWVudCkpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCByZW1vdmVkTm9kZUlkczogQXJyYXk8bnVtYmVyPiA9IFtdO1xuICAgICAgZm9yIChjb25zdCBub2RlIG9mIG11dGF0aW9uLnJlbW92ZWROb2Rlcykge1xuICAgICAgICBpZiAodGhpcy5pc0lnbm9yZWRFbGVtZW50KG5vZGUgYXMgRWxlbWVudCB8IFRleHQpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdmlydHVhbERvbUVsZW1lbnQgPSB0aGlzLmdldFZpcnR1YWxEb21FbGVtZW50Rm9yUmVhbEVsZW1lbnRPclRocm93KFxuICAgICAgICAgIG5vZGUgYXMgRWxlbWVudCB8IFRleHQsXG4gICAgICAgICk7XG4gICAgICAgIHJlbW92ZWROb2RlSWRzLnB1c2godmlydHVhbERvbUVsZW1lbnQubm9kZUlkKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbXV0YXRpb25SZWNvcmQ6IFN0YXRpY1ZpcnR1YWxEb21NdXRhdGlvbklkc1JlY29yZCA9IHtcbiAgICAgICAgdHlwZTogbXV0YXRpb24udHlwZSxcbiAgICAgICAgdGFyZ2V0SWQ6IHRhcmdldEVsZW1lbnQubm9kZUlkLFxuICAgICAgICBhZGRlZE5vZGVzLFxuICAgICAgICByZW1vdmVkTm9kZUlkcyxcbiAgICAgICAgcHJldmlvdXNTaWJsaW5nSWQ6XG4gICAgICAgICAgZmlyc3ROb25JZ25vcmVkUHJldmlvdXNTaWJsaW5nICE9PSBudWxsXG4gICAgICAgICAgICA/IHRoaXMuZ2V0VmlydHVhbERvbUVsZW1lbnRGb3JSZWFsRWxlbWVudE9yVGhyb3coZmlyc3ROb25JZ25vcmVkUHJldmlvdXNTaWJsaW5nKS5ub2RlSWRcbiAgICAgICAgICAgIDogbnVsbCxcbiAgICAgICAgYXR0cmlidXRlOiBtdXRhdGlvbi5hdHRyaWJ1dGVOYW1lXG4gICAgICAgICAgPyB7XG4gICAgICAgICAgICAgIGF0dHJpYnV0ZU5hbWU6IG11dGF0aW9uLmF0dHJpYnV0ZU5hbWUsXG4gICAgICAgICAgICAgIHZhbHVlOiAobXV0YXRpb24udGFyZ2V0IGFzIEVsZW1lbnQpLmdldEF0dHJpYnV0ZShtdXRhdGlvbi5hdHRyaWJ1dGVOYW1lKSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICA6IG51bGwsXG4gICAgICB9O1xuXG4gICAgICB0aGlzLmNhbGxiYWNrKHtcbiAgICAgICAgbXV0YXRpb246IG11dGF0aW9uUmVjb3JkLFxuICAgICAgICBkb2N1bWVudFRpbWU6IHRoaXMuZ2V0RG9jdW1lbnRUaW1lKCksXG4gICAgICB9KTtcblxuICAgICAgdGhpcy5yZW1vdmVLbm93bk5vZGVzSW5NdXRhdGlvbihtdXRhdGlvbik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhZGRLbm93bk5vZGVzSW5NdXRhdGlvbihtdXRhdGlvbjogTXV0YXRpb25SZWNvcmQpOiB2b2lkIHtcbiAgICBjb25zdCB0YXJnZXROb2RlID0gbXV0YXRpb24udGFyZ2V0IGFzIEVsZW1lbnQgfCBUZXh0O1xuICAgIGNvbnN0IHZpcnR1YWxEb21FbGVtZW50ID0gdGhpcy5yZWFsRWxlbWVudFRvVmlydHVhbEVsZW1lbnQuZ2V0KHRhcmdldE5vZGUpO1xuICAgIGlmICghdmlydHVhbERvbUVsZW1lbnQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJVbmtub3duIG5vZGUgaW4gYWRkS25vd25Ob2Rlc0luTXV0YXRpb246XCIgKyB0YXJnZXROb2RlICsgXCIsXCIgKyBtdXRhdGlvbi50eXBlLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKG11dGF0aW9uLnR5cGUgPT09IFwiY2hpbGRMaXN0XCIpIHtcbiAgICAgIGxldCBwcmV2aW91c1NpYmxpbmcgPSBtdXRhdGlvbi5wcmV2aW91c1NpYmxpbmc7XG4gICAgICBsZXQgaW5kZXggPSAwO1xuICAgICAgd2hpbGUgKHByZXZpb3VzU2libGluZyAmJiB0aGlzLmlzSWdub3JlZEVsZW1lbnQocHJldmlvdXNTaWJsaW5nIGFzIEVsZW1lbnQgfCBUZXh0KSkge1xuICAgICAgICBwcmV2aW91c1NpYmxpbmcgPSBwcmV2aW91c1NpYmxpbmcucHJldmlvdXNTaWJsaW5nO1xuICAgICAgfVxuICAgICAgaWYgKHByZXZpb3VzU2libGluZykge1xuICAgICAgICBjb25zdCBwcmV2aW91c1NpYmxpbmdFbGVtZW50ID0gdGhpcy5yZWFsRWxlbWVudFRvVmlydHVhbEVsZW1lbnQuZ2V0KFxuICAgICAgICAgIHByZXZpb3VzU2libGluZyBhcyBFbGVtZW50IHwgVGV4dCxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCFwcmV2aW91c1NpYmxpbmdFbGVtZW50KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBwcmV2aW91cyBzaWJsaW5nXCIpO1xuICAgICAgICB9XG4gICAgICAgIGluZGV4ID0gdmlydHVhbERvbUVsZW1lbnQuY2hpbGROb2Rlcy5pbmRleE9mKHByZXZpb3VzU2libGluZ0VsZW1lbnQpO1xuICAgICAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUHJldmlvdXMgc2libGluZyBpcyBub3QgY3VycmVudGx5IGEgY2hpbGQgb2YgdGhlIHBhcmVudCBlbGVtZW50XCIpO1xuICAgICAgICB9XG4gICAgICAgIGluZGV4ICs9IDE7XG4gICAgICB9XG4gICAgICBtdXRhdGlvbi5hZGRlZE5vZGVzLmZvckVhY2goKG5vZGU6IE5vZGUpID0+IHtcbiAgICAgICAgY29uc3QgYXNFbGVtZW50T3JUZXh0ID0gbm9kZSBhcyBFbGVtZW50IHwgVGV4dDtcbiAgICAgICAgY29uc3QgY2hpbGRWaXJ0dWFsRG9tRWxlbWVudCA9IHRoaXMuY3JlYXRlVmlydHVhbERvbUVsZW1lbnRXaXRoQ2hpbGRyZW4oXG4gICAgICAgICAgYXNFbGVtZW50T3JUZXh0LFxuICAgICAgICAgIHZpcnR1YWxEb21FbGVtZW50LFxuICAgICAgICApO1xuICAgICAgICBpZiAoY2hpbGRWaXJ0dWFsRG9tRWxlbWVudCkge1xuICAgICAgICAgIGlmICh2aXJ0dWFsRG9tRWxlbWVudC5jaGlsZE5vZGVzLmluZGV4T2YoY2hpbGRWaXJ0dWFsRG9tRWxlbWVudCkgPT09IC0xKSB7XG4gICAgICAgICAgICB2aXJ0dWFsRG9tRWxlbWVudC5jaGlsZE5vZGVzLnNwbGljZShpbmRleCwgMCwgY2hpbGRWaXJ0dWFsRG9tRWxlbWVudCk7XG4gICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChtdXRhdGlvbi50eXBlID09PSBcImF0dHJpYnV0ZXNcIikge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgIGNvbnN0IGF0dHJpYnV0ZU5hbWUgPSBtdXRhdGlvbi5hdHRyaWJ1dGVOYW1lITtcbiAgICAgIGlmICh0aGlzLmlzSWdub3JlZEF0dHJpYnV0ZSh0YXJnZXROb2RlLCBhdHRyaWJ1dGVOYW1lKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBhdHRyaWJ1dGVWYWx1ZSA9ICh0YXJnZXROb2RlIGFzIEVsZW1lbnQpLmdldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lKTtcbiAgICAgIGlmIChhdHRyaWJ1dGVWYWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICBkZWxldGUgdmlydHVhbERvbUVsZW1lbnQuYXR0cmlidXRlc1thdHRyaWJ1dGVOYW1lXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZpcnR1YWxEb21FbGVtZW50LmF0dHJpYnV0ZXNbYXR0cmlidXRlTmFtZV0gPSBhdHRyaWJ1dGVWYWx1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG11dGF0aW9uLnR5cGUgPT09IFwiY2hhcmFjdGVyRGF0YVwiKSB7XG4gICAgICB2aXJ0dWFsRG9tRWxlbWVudC50ZXh0Q29udGVudCA9IHRhcmdldE5vZGUudGV4dENvbnRlbnQgPyB0YXJnZXROb2RlLnRleHRDb250ZW50IDogdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlS25vd25Ob2Rlc0luTXV0YXRpb24obXV0YXRpb246IE11dGF0aW9uUmVjb3JkKTogdm9pZCB7XG4gICAgY29uc3QgdGFyZ2V0Tm9kZSA9IG11dGF0aW9uLnRhcmdldCBhcyBFbGVtZW50IHwgVGV4dDtcbiAgICBjb25zdCB2aXJ0dWFsRG9tRWxlbWVudCA9IHRoaXMucmVhbEVsZW1lbnRUb1ZpcnR1YWxFbGVtZW50LmdldCh0YXJnZXROb2RlKTtcbiAgICBpZiAoIXZpcnR1YWxEb21FbGVtZW50KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG5vZGUgaW4gbXV0YXRpb24gbGlzdDpcIiArIHRhcmdldE5vZGUgKyBcIiwgXCIgKyBtdXRhdGlvbi50eXBlKTtcbiAgICB9XG4gICAgaWYgKG11dGF0aW9uLnR5cGUgPT09IFwiY2hpbGRMaXN0XCIpIHtcbiAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiBtdXRhdGlvbi5yZW1vdmVkTm9kZXMpIHtcbiAgICAgICAgY29uc3QgYXNFbGVtZW50T3JUZXh0ID0gbm9kZSBhcyBFbGVtZW50IHwgVGV4dDtcbiAgICAgICAgaWYgKHRoaXMuaXNJZ25vcmVkRWxlbWVudChhc0VsZW1lbnRPclRleHQpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2hpbGREb21FbGVtZW50ID0gdGhpcy5yZWFsRWxlbWVudFRvVmlydHVhbEVsZW1lbnQuZ2V0KGFzRWxlbWVudE9yVGV4dCk7XG4gICAgICAgIGlmICghY2hpbGREb21FbGVtZW50KSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKHRoaXMuaHRtbFBhdGgsIFwiVW5rbm93biBub2RlIGluIHJlbW92ZUtub3duTm9kZXNJbk11dGF0aW9uXCIpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucmVtb3ZlVmlydHVhbERvbUVsZW1lbnQoY2hpbGREb21FbGVtZW50KTtcbiAgICAgICAgICBjb25zdCBpbmRleCA9IHZpcnR1YWxEb21FbGVtZW50LmNoaWxkTm9kZXMuaW5kZXhPZihjaGlsZERvbUVsZW1lbnQpO1xuICAgICAgICAgIHZpcnR1YWxEb21FbGVtZW50LmNoaWxkTm9kZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlVmlydHVhbERvbUVsZW1lbnQodmlydHVhbERvbUVsZW1lbnQ6IExpdmVWaXJ0dWFsRG9tRWxlbWVudCk6IHZvaWQge1xuICAgIHRoaXMubm9kZUlkVG9Ob2RlLmRlbGV0ZSh2aXJ0dWFsRG9tRWxlbWVudC5ub2RlSWQpO1xuICAgIHRoaXMubm9kZVRvTm9kZUlkLmRlbGV0ZSh2aXJ0dWFsRG9tRWxlbWVudCk7XG4gICAgdGhpcy5yZWFsRWxlbWVudFRvVmlydHVhbEVsZW1lbnQuZGVsZXRlKHZpcnR1YWxEb21FbGVtZW50LnJlYWxFbGVtZW50KTtcbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIHZpcnR1YWxEb21FbGVtZW50LmNoaWxkTm9kZXMpIHtcbiAgICAgIHRoaXMucmVtb3ZlVmlydHVhbERvbUVsZW1lbnQoY2hpbGQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlVmlydHVhbERvbUVsZW1lbnRXaXRoQ2hpbGRyZW4oXG4gICAgbm9kZTogRWxlbWVudCB8IFRleHQsXG4gICAgcGFyZW50OiBMaXZlVmlydHVhbERvbUVsZW1lbnQgfCBudWxsLFxuICApOiBMaXZlVmlydHVhbERvbUVsZW1lbnQgfCBudWxsIHtcbiAgICBjb25zdCB2aXJ0dWFsRWxlbWVudCA9IHRoaXMuY3JlYXRlVmlydHVhbERvbUVsZW1lbnQobm9kZSwgcGFyZW50KTtcbiAgICBpZiAoIXZpcnR1YWxFbGVtZW50KSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKChub2RlIGFzIEVsZW1lbnQpLmNoaWxkTm9kZXMpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgKG5vZGUgYXMgRWxlbWVudCkuY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBjaGlsZCA9IChub2RlIGFzIEVsZW1lbnQpLmNoaWxkTm9kZXNbaV07XG4gICAgICAgIGNvbnN0IGNoaWxkVmlydHVhbEVsZW1lbnQgPSB0aGlzLmNyZWF0ZVZpcnR1YWxEb21FbGVtZW50V2l0aENoaWxkcmVuKFxuICAgICAgICAgIGNoaWxkIGFzIEVsZW1lbnQgfCBUZXh0LFxuICAgICAgICAgIHZpcnR1YWxFbGVtZW50LFxuICAgICAgICApO1xuICAgICAgICBpZiAoY2hpbGRWaXJ0dWFsRWxlbWVudCkge1xuICAgICAgICAgIHZpcnR1YWxFbGVtZW50LmNoaWxkTm9kZXMucHVzaChjaGlsZFZpcnR1YWxFbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2aXJ0dWFsRWxlbWVudDtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlVmlydHVhbERvbUVsZW1lbnQoXG4gICAgbm9kZTogRWxlbWVudCB8IFRleHQsXG4gICAgcGFyZW50OiBMaXZlVmlydHVhbERvbUVsZW1lbnQgfCBudWxsLFxuICApOiBMaXZlVmlydHVhbERvbUVsZW1lbnQgfCBudWxsIHtcbiAgICBpZiAodGhpcy5pc0lnbm9yZWRFbGVtZW50KG5vZGUpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgZXhpc3RpbmdWYWx1ZSA9IHRoaXMucmVhbEVsZW1lbnRUb1ZpcnR1YWxFbGVtZW50LmdldChub2RlKTtcbiAgICBpZiAoZXhpc3RpbmdWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb2RlIGFscmVhZHkgaGFzIGEgdmlydHVhbCBlbGVtZW50OiBcIiArIG5vZGUubm9kZU5hbWUpO1xuICAgIH1cbiAgICBpZiAoIW5vZGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBhc3NpZ24gbm9kZSBpZCB0byBudWxsXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IGF0dHJpYnV0ZXM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgICBpZiAoKG5vZGUgYXMgYW55KS5hdHRyaWJ1dGVzKSB7XG4gICAgICBjb25zdCBhc0hUTUxFbGVtZW50ID0gbm9kZSBhcyBIVE1MRWxlbWVudDtcbiAgICAgIGZvciAoY29uc3Qga2V5IG9mIGFzSFRNTEVsZW1lbnQuZ2V0QXR0cmlidXRlTmFtZXMoKSkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGFzSFRNTEVsZW1lbnQuZ2V0QXR0cmlidXRlKGtleSk7XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk51bGwgYXR0cmlidXRlIHZhbHVlIGZvciBrZXk6IFwiICsga2V5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuaXNJZ25vcmVkQXR0cmlidXRlKG5vZGUsIGtleSkpIHtcbiAgICAgICAgICBhdHRyaWJ1dGVzW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IG5vZGVJZCA9IHRoaXMubmV4dE5vZGVJZCsrO1xuICAgIGNvbnN0IHZpcnR1YWxFbGVtZW50OiBMaXZlVmlydHVhbERvbUVsZW1lbnQgPSB7XG4gICAgICBub2RlSWQsXG4gICAgICB0YWc6IG5vZGUubm9kZU5hbWUsXG4gICAgICBhdHRyaWJ1dGVzLFxuICAgICAgY2hpbGROb2RlczogW10sXG4gICAgICByZWFsRWxlbWVudDogbm9kZSxcbiAgICAgIHBhcmVudCxcbiAgICB9O1xuICAgIGlmIChub2RlIGluc3RhbmNlb2YgdGhpcy5kb21SdW5uZXIuZ2V0V2luZG93KCkuVGV4dCAmJiBub2RlLnRleHRDb250ZW50KSB7XG4gICAgICB2aXJ0dWFsRWxlbWVudC50ZXh0Q29udGVudCA9IG5vZGUudGV4dENvbnRlbnQ7XG4gICAgfVxuICAgIHRoaXMubm9kZVRvTm9kZUlkLnNldCh2aXJ0dWFsRWxlbWVudCwgbm9kZUlkKTtcbiAgICB0aGlzLm5vZGVJZFRvTm9kZS5zZXQobm9kZUlkLCB2aXJ0dWFsRWxlbWVudCk7XG4gICAgdGhpcy5yZWFsRWxlbWVudFRvVmlydHVhbEVsZW1lbnQuc2V0KG5vZGUsIHZpcnR1YWxFbGVtZW50KTtcbiAgICByZXR1cm4gdmlydHVhbEVsZW1lbnQ7XG4gIH1cblxuICBwcml2YXRlIGdldEZpcnN0Tm9uSWdub3JlZFByZXZpb3VzU2libGluZyhub2RlOiBFbGVtZW50IHwgVGV4dCk6IEVsZW1lbnQgfCBUZXh0IHwgbnVsbCB7XG4gICAgbGV0IGN1cnJlbnROb2RlID0gbm9kZTtcbiAgICBpZiAoIXRoaXMuaXNJZ25vcmVkRWxlbWVudChjdXJyZW50Tm9kZSkpIHtcbiAgICAgIHJldHVybiBjdXJyZW50Tm9kZTtcbiAgICB9XG4gICAgd2hpbGUgKGN1cnJlbnROb2RlICYmIGN1cnJlbnROb2RlLnByZXZpb3VzU2libGluZykge1xuICAgICAgY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZS5wcmV2aW91c1NpYmxpbmcgYXMgRWxlbWVudCB8IFRleHQ7XG4gICAgICBpZiAoIXRoaXMuaXNJZ25vcmVkRWxlbWVudChjdXJyZW50Tm9kZSkpIHtcbiAgICAgICAgcmV0dXJuIGN1cnJlbnROb2RlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0VmlydHVhbERvbUVsZW1lbnRGb3JSZWFsRWxlbWVudE9yVGhyb3coXG4gICAgcmVhbEVsZW1lbnQ6IEVsZW1lbnQgfCBUZXh0LFxuICApOiBMaXZlVmlydHVhbERvbUVsZW1lbnQge1xuICAgIGNvbnN0IHZpcnR1YWxFbGVtZW50ID0gdGhpcy5yZWFsRWxlbWVudFRvVmlydHVhbEVsZW1lbnQuZ2V0KHJlYWxFbGVtZW50KTtcbiAgICBpZiAoIXZpcnR1YWxFbGVtZW50KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFZpcnR1YWwgZWxlbWVudCBub3QgZm91bmQgZm9yIHJlYWwgZWxlbWVudGApO1xuICAgIH1cbiAgICByZXR1cm4gdmlydHVhbEVsZW1lbnQ7XG4gIH1cblxuICBwcml2YXRlIGlzSWdub3JlZEVsZW1lbnQobm9kZTogRWxlbWVudCB8IFRleHQpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5pZ25vcmVUZXh0Tm9kZXMgJiYgbm9kZSBpbnN0YW5jZW9mIHRoaXMuZG9tUnVubmVyLmdldFdpbmRvdygpLlRleHQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSBpZiAobm9kZSBpbnN0YW5jZW9mIHRoaXMuZG9tUnVubmVyLmdldFdpbmRvdygpLkhUTUxTY3JpcHRFbGVtZW50KSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKG5vZGUgaW5zdGFuY2VvZiB0aGlzLmRvbVJ1bm5lci5nZXRXaW5kb3coKS5Db21tZW50KSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0lnbm9yZWRBdHRyaWJ1dGUobm9kZTogRWxlbWVudCB8IFRleHQsIGF0dHJpYnV0ZU5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBhdHRyaWJ1dGVOYW1lLnN0YXJ0c1dpdGgoXCJvblwiKTtcbiAgfVxuXG4gIHB1YmxpYyBkaXNwYXRjaFJlbW90ZUV2ZW50RnJvbUNvbm5lY3Rpb25JZChjb25uZWN0aW9uSWQ6IG51bWJlciwgcmVtb3RlRXZlbnQ6IFJlbW90ZUV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgZG9tTm9kZSA9IHRoaXMubm9kZUlkVG9Ob2RlLmdldChyZW1vdGVFdmVudC5ub2RlSWQpO1xuICAgIGlmICghZG9tTm9kZSkge1xuICAgICAgY29uc29sZS5lcnJvcihcIlVua25vd24gbm9kZSBJRCBpbiByZW1vdGUgZXZlbnQ6IFwiICsgcmVtb3RlRXZlbnQubm9kZUlkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZG9tTm9kZSBpbnN0YW5jZW9mIHRoaXMuZG9tUnVubmVyLmdldFdpbmRvdygpLlRleHQpIHtcbiAgICAgIGNvbnNvbGUud2FybihcIkNhbm5vdCBkaXNwYXRjaCByZW1vdGUgZXZlbnQgdG8gdGV4dCBub2RlXCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuZG9tUnVubmVyLmRpc3BhdGNoUmVtb3RlRXZlbnRGcm9tQ29ubmVjdGlvbklkKFxuICAgICAgY29ubmVjdGlvbklkLFxuICAgICAgZG9tTm9kZS5yZWFsRWxlbWVudCBhcyBFbGVtZW50LFxuICAgICAgcmVtb3RlRXZlbnQsXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBkaXNwb3NlKCkge1xuICAgIGNsZWFySW50ZXJ2YWwodGhpcy5kb2N1bWVudFRpbWVJbnRlcnZhbFRpbWVyKTtcbiAgICB0aGlzLmRvbVJ1bm5lci5kaXNwb3NlKCk7XG4gIH1cblxuICBwcml2YXRlIGdldERvY3VtZW50VGltZSgpIHtcbiAgICByZXR1cm4gdGhpcy5kb21SdW5uZXIuZ2V0RG9jdW1lbnRUaW1lKCk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBSZW1vdGVFdmVudCB9IGZyb20gXCJAbW1sLWlvL25ldHdvcmtlZC1kb20tcHJvdG9jb2xcIjtcbmltcG9ydCB7IERPTVJ1bm5lckZhY3RvcnksIERPTVJ1bm5lckludGVyZmFjZSwgRE9NUnVubmVyTWVzc2FnZSB9IGZyb20gXCJAbW1sLWlvL29ic2VydmFibGUtZG9tXCI7XG5cbmV4cG9ydCBjb25zdCBXZWJCcm93c2VyRE9NUnVubmVyRmFjdG9yeTogRE9NUnVubmVyRmFjdG9yeSA9IChcbiAgaHRtbFBhdGg6IHN0cmluZyxcbiAgaHRtbENvbnRlbnRzOiBzdHJpbmcsXG4gIHBhcmFtczogb2JqZWN0LFxuICBjYWxsYmFjazogKG11dGF0aW9uTGlzdDogRE9NUnVubmVyTWVzc2FnZSkgPT4gdm9pZCxcbik6IERPTVJ1bm5lckludGVyZmFjZSA9PiB7XG4gIHJldHVybiBuZXcgV2ViQnJvd3NlckRPTVJ1bm5lcihodG1sUGF0aCwgaHRtbENvbnRlbnRzLCBwYXJhbXMsIGNhbGxiYWNrKTtcbn07XG5cbmNvbnN0IGRvY3VtZW50TG9hZFRpbWUgPSBEYXRlLm5vdygpO1xuXG5leHBvcnQgY2xhc3MgV2ViQnJvd3NlckRPTVJ1bm5lciBpbXBsZW1lbnRzIERPTVJ1bm5lckludGVyZmFjZSB7XG4gIHByaXZhdGUgbXV0YXRpb25PYnNlcnZlcjogTXV0YXRpb25PYnNlcnZlcjtcbiAgcHJpdmF0ZSBodG1sUGF0aDogc3RyaW5nO1xuICBwcml2YXRlIGNhbGxiYWNrOiAoZG9tUnVubmVyTWVzc2FnZTogRE9NUnVubmVyTWVzc2FnZSkgPT4gdm9pZDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBodG1sUGF0aDogc3RyaW5nLFxuICAgIGh0bWxDb250ZW50czogc3RyaW5nLFxuICAgIHBhcmFtczogb2JqZWN0LFxuICAgIGNhbGxiYWNrOiAoZG9tUnVubmVyTWVzc2FnZTogRE9NUnVubmVyTWVzc2FnZSkgPT4gdm9pZCxcbiAgKSB7XG4gICAgdGhpcy5odG1sUGF0aCA9IGh0bWxQYXRoO1xuICAgIHRoaXMuY2FsbGJhY2sgPSBjYWxsYmFjaztcblxuICAgIC8vIEZvcndhcmQgY29uc29sZSBtZXNzYWdlc1xuICAgIGZvciAoY29uc3QgbGV2ZWwgb2YgW1wiZXJyb3JcIiwgXCJ3YXJuXCIsIFwiaW5mb1wiLCBcImxvZ1wiXSBhcyBjb25zdCkge1xuICAgICAgY29uc3QgZGVmYXVsdEZuID0gd2luZG93LmNvbnNvbGVbbGV2ZWxdO1xuXG4gICAgICB3aW5kb3cuY29uc29sZVtsZXZlbF0gPSAoLi4uYXJncykgPT4ge1xuICAgICAgICBjYWxsYmFjayh7XG4gICAgICAgICAgbG9nTWVzc2FnZToge1xuICAgICAgICAgICAgbGV2ZWwsXG4gICAgICAgICAgICBjb250ZW50OiBhcmdzLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgICAgICBkZWZhdWx0Rm4oLi4uYXJncyk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIEZvcndhcmQgdW5jYXVnaHQgZXJyb3JzXG4gICAgd2luZG93Lm9uZXJyb3IgPSAobWVzc2FnZSwgc291cmNlLCBsaW5lLCBjb2x1bW4sIGVycm9yKSA9PiB7XG4gICAgICBjYWxsYmFjayh7XG4gICAgICAgIGxvZ01lc3NhZ2U6IHtcbiAgICAgICAgICBsZXZlbDogXCJzeXN0ZW1cIixcbiAgICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIG1lc3NhZ2UsXG4gICAgICAgICAgICAgIHR5cGU6IGVycm9yPy5uYW1lLFxuICAgICAgICAgICAgICBsaW5lLFxuICAgICAgICAgICAgICBjb2x1bW4sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgbGV0IGRpZFNlbmRMb2FkID0gZmFsc2U7XG5cbiAgICB0aGlzLm11dGF0aW9uT2JzZXJ2ZXIgPSBuZXcgd2luZG93Lk11dGF0aW9uT2JzZXJ2ZXIoKG11dGF0aW9uTGlzdCkgPT4ge1xuICAgICAgaWYgKCFkb2N1bWVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoIWRpZFNlbmRMb2FkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk11dGF0aW9uT2JzZXJ2ZXIgY2FsbGVkIGJlZm9yZSBsb2FkXCIpO1xuICAgICAgfVxuICAgICAgdGhpcy5jYWxsYmFjayh7XG4gICAgICAgIG11dGF0aW9uTGlzdCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgKHdpbmRvdyBhcyBhbnkpLnBhcmFtcyA9IHBhcmFtcztcblxuICAgIGNvbnN0IGZpbmlzaExvYWQgPSAoKSA9PiB7XG4gICAgICBpZiAoZGlkU2VuZExvYWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiZmluaXNoTG9hZCBjYWxsZWQgdHdpY2VcIik7XG4gICAgICB9XG4gICAgICBkaWRTZW5kTG9hZCA9IHRydWU7XG4gICAgICB0aGlzLmNhbGxiYWNrKHtcbiAgICAgICAgbG9hZGVkOiB0cnVlLFxuICAgICAgfSk7XG4gICAgICB0aGlzLm11dGF0aW9uT2JzZXJ2ZXIub2JzZXJ2ZSh3aW5kb3cuZG9jdW1lbnQsIHtcbiAgICAgICAgYXR0cmlidXRlczogdHJ1ZSxcbiAgICAgICAgY2hpbGRMaXN0OiB0cnVlLFxuICAgICAgICBzdWJ0cmVlOiB0cnVlLFxuICAgICAgICBjaGFyYWN0ZXJEYXRhOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfTtcbiAgICBpZiAoZG9jdW1lbnQuYm9keSkge1xuICAgICAgc2V0VGltZW91dChmaW5pc2hMb2FkLCAwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJET01Db250ZW50TG9hZGVkXCIsIGZpbmlzaExvYWQpO1xuICAgIH1cbiAgfVxuXG4gIGFkZElQQ1dlYnNvY2tldCgpOiB2b2lkIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb3QgaW1wbGVtZW50ZWQuXCIpO1xuICB9XG5cbiAgZGlzcGF0Y2hSZW1vdGVFdmVudEZyb21Db25uZWN0aW9uSWQoXG4gICAgY29ubmVjdGlvbklkOiBudW1iZXIsXG4gICAgcmVhbEVsZW1lbnQ6IEVsZW1lbnQsXG4gICAgcmVtb3RlRXZlbnQ6IFJlbW90ZUV2ZW50LFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBidWJibGVzID0gcmVtb3RlRXZlbnQuYnViYmxlcyB8fCBmYWxzZTtcbiAgICBjb25zdCByZW1vdGVFdmVudE9iamVjdCA9IG5ldyBDdXN0b21FdmVudChyZW1vdGVFdmVudC5uYW1lLCB7XG4gICAgICBidWJibGVzLFxuICAgICAgZGV0YWlsOiB7IC4uLnJlbW90ZUV2ZW50LnBhcmFtcywgY29ubmVjdGlvbklkIH0sXG4gICAgfSk7XG5cbiAgICAvLyBEaXNwYXRjaCB0aGUgZXZlbnQgdmlhIEphdmFTY3JpcHQuXG4gICAgcmVhbEVsZW1lbnQuZGlzcGF0Y2hFdmVudChyZW1vdGVFdmVudE9iamVjdCk7XG4gIH1cblxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIC8vIFRPRE8gLSBoYW5kbGUgZGlzcG9zZVxuICAgIGNvbnNvbGUubG9nKFwiV2ViQnJvd3NlckRPTVJ1bm5lci5kaXNwb3NlXCIpO1xuICB9XG5cbiAgZ2V0RG9jdW1lbnQoKTogRG9jdW1lbnQge1xuICAgIHJldHVybiBkb2N1bWVudDtcbiAgfVxuXG4gIGdldERvY3VtZW50VGltZSgpOiBudW1iZXIge1xuICAgIGlmIChkb2N1bWVudC50aW1lbGluZSAmJiBkb2N1bWVudC50aW1lbGluZS5jdXJyZW50VGltZSkge1xuICAgICAgcmV0dXJuIGRvY3VtZW50LnRpbWVsaW5lLmN1cnJlbnRUaW1lO1xuICAgIH1cbiAgICByZXR1cm4gRGF0ZS5ub3coKSAtIGRvY3VtZW50TG9hZFRpbWU7XG4gIH1cblxuICAvLyBUT0RPIC0gcmVzb2x2ZSB0eXBlcyAoV2luZG93IG5lZWRzIHRvIGV4cG9zZSBjbGFzc2VzIHN1Y2ggYXMgQ3VzdG9tRXZlbnQgYXMgcHJvcGVydGllcylcbiAgZ2V0V2luZG93KCk6IGFueSB7XG4gICAgcmV0dXJuIHdpbmRvdztcbiAgfVxufVxuIiwgImltcG9ydCB7XG4gIEZyb21JbnN0YW5jZU1lc3NhZ2VUeXBlcyxcbiAgVG9JbnN0YW5jZU1lc3NhZ2VUeXBlcyxcbn0gZnJvbSBcIkBtbWwtaW8vbmV0d29ya2VkLWRvbS13ZWItcnVubmVyL3NyYy9tZXNzYWdlLXR5cGVzXCI7XG5pbXBvcnQgeyBPYnNlcnZhYmxlRG9tIH0gZnJvbSBcIkBtbWwtaW8vb2JzZXJ2YWJsZS1kb20vc3JjL09ic2VydmFibGVEb21cIjtcbmltcG9ydCB7IE9ic2VydmFibGVEb21NZXNzYWdlLCBPYnNlcnZhYmxlRE9NUGFyYW1ldGVycyB9IGZyb20gXCJAbW1sLWlvL29ic2VydmFibGUtZG9tLWNvbW1vblwiO1xuXG5pbXBvcnQgeyBXZWJCcm93c2VyRE9NUnVubmVyRmFjdG9yeSB9IGZyb20gXCIuL1dlYkJyb3dzZXJET01SdW5uZXJcIjtcblxuLy8gVGhpcyBydW5zIGluIHRoZSBpZnJhbWUgdGhhdCB3aWxsIGV4ZWN1dGUgdGhlIGRvY3VtZW50IHNjcmlwdCB0byBzZXR1cCB0aGUgbGlzdGVuaW5nIGZvciBldmVudHMgbWVzc2FnZXNcbmV4cG9ydCBmdW5jdGlvbiBzZXR1cElmcmFtZVdlYlJ1bm5lcihhcmdzU3RyaW5nOiBzdHJpbmcpIHtcbiAgY29uc3Qgb2JzZXJ2YWJsZURPTVBhcmFtcyA9IEpTT04ucGFyc2UoYXRvYihhcmdzU3RyaW5nKSkgYXMgT2JzZXJ2YWJsZURPTVBhcmFtZXRlcnM7XG5cbiAgY29uc3Qgc2VuZE1lc3NhZ2VUb0hhbmRsZXIgPSAobWVzc2FnZTogRnJvbUluc3RhbmNlTWVzc2FnZVR5cGVzKSA9PiB7XG4gICAgd2luZG93LnBhcmVudC5wb3N0TWVzc2FnZShKU09OLnN0cmluZ2lmeShtZXNzYWdlKSwgXCIqXCIpO1xuICB9O1xuXG4gIGNvbnN0IG9ic2VydmFibGVET00gPSBuZXcgT2JzZXJ2YWJsZURvbShcbiAgICB7XG4gICAgICAuLi5vYnNlcnZhYmxlRE9NUGFyYW1zLFxuICAgICAgaHRtbENvbnRlbnRzOiBcIlwiLCAvLyBUaGlzIG11c3QgYmUgZW1wdHkgYXMgdGhlIGNvbnRlbnRzIGFyZSBhc3N1bWVkIHRvIGJlIHByb3ZpZGVkIGJ5IHRoZSBzcmNkb2NcbiAgICB9LFxuICAgIChvYnNlcnZhYmxlRG9tTWVzc2FnZTogT2JzZXJ2YWJsZURvbU1lc3NhZ2UpID0+IHtcbiAgICAgIHNlbmRNZXNzYWdlVG9IYW5kbGVyKHtcbiAgICAgICAgdHlwZTogXCJkb21cIixcbiAgICAgICAgbWVzc2FnZTogb2JzZXJ2YWJsZURvbU1lc3NhZ2UsXG4gICAgICB9KTtcbiAgICB9LFxuICAgIFdlYkJyb3dzZXJET01SdW5uZXJGYWN0b3J5LFxuICApO1xuXG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwibWVzc2FnZVwiLCAoZSkgPT4ge1xuICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoZS5kYXRhKSBhcyBUb0luc3RhbmNlTWVzc2FnZVR5cGVzO1xuICAgIGlmIChwYXJzZWQudHlwZSA9PT0gXCJkaXNwYXRjaFJlbW90ZUV2ZW50RnJvbUNvbm5lY3Rpb25JZFwiKSB7XG4gICAgICBvYnNlcnZhYmxlRE9NLmRpc3BhdGNoUmVtb3RlRXZlbnRGcm9tQ29ubmVjdGlvbklkKHBhcnNlZC5jb25uZWN0aW9uSWQsIHBhcnNlZC5ldmVudCk7XG4gICAgfVxuICB9KTtcbn1cbiIsICJpbXBvcnQgeyBzZXR1cElmcmFtZVdlYlJ1bm5lciB9IGZyb20gXCIuL0lmcmFtZVdlYlJ1bm5lclwiO1xuXG5jb25zdCBhcmdzID0gKHdpbmRvdyBhcyBhbnkpLmFyZ3M7XG5zZXR1cElmcmFtZVdlYlJ1bm5lcihhcmdzKTtcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUlPLFNBQVMsMEJBQTBCLElBQW9EO0FBQzVGLFNBQU87QUFBQSxJQUNMLFFBQVEsR0FBRztBQUFBLElBQ1gsS0FBSyxHQUFHO0FBQUEsSUFDUixZQUFZLEdBQUc7QUFBQSxJQUNmLFlBQVksR0FBRyxXQUFXLElBQUksQ0FBQyxVQUFVLDBCQUEwQixLQUFLLENBQUM7QUFBQSxJQUN6RSxhQUFhLEdBQUc7QUFBQSxFQUNsQjtBQUNGOzs7QUNxQ08sSUFBTSxnQkFBTixNQUFzRDtBQUFBLEVBWTNELFlBQ0UseUJBQ0EsVUFDQSxlQUNBO0FBZkYsU0FBUSxlQUFlLG9CQUFJLElBQW1DO0FBQzlELFNBQVEsZUFBZSxvQkFBSSxJQUFtQztBQUM5RCxTQUFRLDhCQUE4QixvQkFBSSxJQUEyQztBQUNyRixTQUFRLGtCQUFrQjtBQUUxQixTQUFRLGFBQWE7QUFXbkIsU0FBSyxXQUFXLHdCQUF3QjtBQUN4QyxTQUFLLGtCQUFrQix3QkFBd0I7QUFDL0MsU0FBSyxXQUFXO0FBRWhCLFNBQUssNEJBQTRCLFlBQVksTUFBTTtBQUNqRCxXQUFLLFNBQVM7QUFBQSxRQUNaLGNBQWMs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\n';
|
|
32
|
+
var build_default = 'var __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __defProps = Object.defineProperties;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropDescs = Object.getOwnPropertyDescriptors;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __getOwnPropSymbols = Object.getOwnPropertySymbols;\nvar __getProtoOf = Object.getPrototypeOf;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __propIsEnum = Object.prototype.propertyIsEnumerable;\nvar __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;\nvar __spreadValues = (a, b) => {\n for (var prop in b ||= {})\n if (__hasOwnProp.call(b, prop))\n __defNormalProp(a, prop, b[prop]);\n if (__getOwnPropSymbols)\n for (var prop of __getOwnPropSymbols(b)) {\n if (__propIsEnum.call(b, prop))\n __defNormalProp(a, prop, b[prop]);\n }\n return a;\n};\nvar __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));\nvar __commonJS = (cb, mod) => function __require() {\n return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;\n};\nvar __copyProps = (to, from, except, desc) => {\n if (from && typeof from === "object" || typeof from === "function") {\n for (let key of __getOwnPropNames(from))\n if (!__hasOwnProp.call(to, key) && key !== except)\n __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });\n }\n return to;\n};\nvar __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(\n // If the importer is in node compatibility mode or this is not an ESM\n // file that has been converted to a CommonJS file using a Babel-\n // compatible transform (i.e. "__esModule" has not been set), then set\n // "default" to the CommonJS "module.exports" for node compatibility.\n isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,\n mod\n));\n\n// ../../observable-dom-common/build/index.js\nvar require_build = __commonJS({\n "../../observable-dom-common/build/index.js"(exports, module2) {\n var __defProp2 = Object.defineProperty;\n var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;\n var __getOwnPropNames2 = Object.getOwnPropertyNames;\n var __hasOwnProp2 = Object.prototype.hasOwnProperty;\n var __export = (target, all) => {\n for (var name in all)\n __defProp2(target, name, { get: all[name], enumerable: true });\n };\n var __copyProps2 = (to, from, except, desc) => {\n if (from && typeof from === "object" || typeof from === "function") {\n for (let key of __getOwnPropNames2(from))\n if (!__hasOwnProp2.call(to, key) && key !== except)\n __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });\n }\n return to;\n };\n var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);\n var src_exports = {};\n __export(src_exports, {\n ADD_CONNECTED_USER_ID_MESSAGE_TYPE: () => ADD_CONNECTED_USER_ID_MESSAGE_TYPE2,\n DISPATCH_REMOTE_EVENT_FROM_CONNECTION_ID_MESSAGE_TYPE: () => DISPATCH_REMOTE_EVENT_FROM_CONNECTION_ID_MESSAGE_TYPE2,\n DOM_MESSAGE_TYPE: () => DOM_MESSAGE_TYPE2,\n REMOVE_CONNECTED_USER_ID_MESSAGE_TYPE: () => REMOVE_CONNECTED_USER_ID_MESSAGE_TYPE2,\n applyMessageToObservableDOMInstance: () => applyMessageToObservableDOMInstance,\n observableDOMInterfaceToMessageSender: () => observableDOMInterfaceToMessageSender\n });\n module2.exports = __toCommonJS(src_exports);\n var ADD_CONNECTED_USER_ID_MESSAGE_TYPE2 = "addConnectedUserId";\n var REMOVE_CONNECTED_USER_ID_MESSAGE_TYPE2 = "removeConnectedUserId";\n var DISPATCH_REMOTE_EVENT_FROM_CONNECTION_ID_MESSAGE_TYPE2 = "dispatchRemoteEventFromConnectionId";\n var DOM_MESSAGE_TYPE2 = "dom";\n function applyMessageToObservableDOMInstance(message, instance) {\n if (message.type === ADD_CONNECTED_USER_ID_MESSAGE_TYPE2) {\n instance.addConnectedUserId(message.connectionId);\n } else if (message.type === REMOVE_CONNECTED_USER_ID_MESSAGE_TYPE2) {\n instance.removeConnectedUserId(message.connectionId);\n } else if (message.type === DISPATCH_REMOTE_EVENT_FROM_CONNECTION_ID_MESSAGE_TYPE2) {\n instance.dispatchRemoteEventFromConnectionId(message.connectionId, message.event);\n } else {\n console.error("Unknown message type", message);\n }\n }\n function observableDOMInterfaceToMessageSender(sender, dispose) {\n const remoteObservableDOM = {\n addConnectedUserId(connectionId) {\n sender({\n type: ADD_CONNECTED_USER_ID_MESSAGE_TYPE2,\n connectionId\n });\n },\n dispatchRemoteEventFromConnectionId(connectionId, remoteEvent) {\n sender({\n type: DISPATCH_REMOTE_EVENT_FROM_CONNECTION_ID_MESSAGE_TYPE2,\n connectionId,\n event: remoteEvent\n });\n },\n dispose() {\n dispose();\n },\n removeConnectedUserId(connectionId) {\n sender({\n type: REMOVE_CONNECTED_USER_ID_MESSAGE_TYPE2,\n connectionId\n });\n }\n };\n return remoteObservableDOM;\n }\n }\n});\n\n// ../../observable-dom/src/utils.ts\nfunction virtualDOMElementToStatic(el) {\n return {\n nodeId: el.nodeId,\n tag: el.tag,\n attributes: el.attributes,\n childNodes: el.childNodes.map((child) => virtualDOMElementToStatic(child)),\n textContent: el.textContent\n };\n}\n\n// ../../observable-dom/src/ObservableDOM.ts\nvar ObservableDOM = class {\n constructor(observableDOMParameters, callback, runnerFactory) {\n this.nodeToNodeId = /* @__PURE__ */ new Map();\n this.nodeIdToNode = /* @__PURE__ */ new Map();\n this.realElementToVirtualElement = /* @__PURE__ */ new Map();\n this.ignoreTextNodes = true;\n this.nextNodeId = 1;\n this.htmlPath = observableDOMParameters.htmlPath;\n this.ignoreTextNodes = observableDOMParameters.ignoreTextNodes;\n this.callback = callback;\n this.documentTimeIntervalTimer = setInterval(() => {\n this.callback(\n {\n documentTime: this.getDocumentTime()\n },\n this\n );\n }, observableDOMParameters.pingIntervalMilliseconds || 5e3);\n this.domRunner = runnerFactory(\n observableDOMParameters.htmlPath,\n observableDOMParameters.htmlContents,\n observableDOMParameters.params,\n (domRunnerMessage) => {\n if (domRunnerMessage.loaded) {\n this.createVirtualDOMElementWithChildren(\n this.domRunner.getDocument(),\n null\n );\n const snapshot = virtualDOMElementToStatic(\n this.getVirtualDOMElementForRealElementOrThrow(\n this.domRunner.getDocument()\n )\n );\n this.callback(\n {\n snapshot,\n documentTime: this.getDocumentTime()\n },\n this\n );\n } else if (domRunnerMessage.mutationList) {\n this.processModificationList(domRunnerMessage.mutationList);\n } else if (domRunnerMessage.logMessage) {\n this.callback(\n {\n logMessage: domRunnerMessage.logMessage,\n documentTime: this.getDocumentTime()\n },\n this\n );\n }\n }\n );\n }\n addConnectedUserId(connectionId) {\n this.domRunner.getWindow().dispatchEvent(\n new (this.domRunner.getWindow()).CustomEvent("connected", {\n detail: { connectionId }\n })\n );\n }\n removeConnectedUserId(connectionId) {\n this.domRunner.getWindow().dispatchEvent(\n new (this.domRunner.getWindow()).CustomEvent("disconnected", {\n detail: { connectionId }\n })\n );\n }\n processModificationList(mutationList) {\n const documentEl = this.domRunner.getDocument();\n const documentVirtualDOMElement = this.realElementToVirtualElement.get(documentEl);\n if (!documentVirtualDOMElement) {\n throw new Error(`document not created in processModificationList`);\n }\n if (mutationList.length > 1) {\n console.error(\n "More than one mutation record received. It is possible that intermediate states are incorrect."\n );\n }\n for (const mutation of mutationList) {\n if (this.isIgnoredElement(mutation.target)) {\n continue;\n }\n if (mutation.type === "attributes" && // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.isIgnoredAttribute(mutation.target, mutation.attributeName)) {\n continue;\n }\n this.addKnownNodesInMutation(mutation);\n const firstNonIgnoredPreviousSibling = mutation.previousSibling ? this.getFirstNonIgnoredPreviousSibling(mutation.previousSibling) : null;\n const targetElement = this.getVirtualDOMElementForRealElementOrThrow(\n mutation.target\n );\n const addedNodes = [];\n for (const node of mutation.addedNodes) {\n if (this.isIgnoredElement(node)) {\n continue;\n }\n const virtualDOMElement = this.getVirtualDOMElementForRealElementOrThrow(\n node\n );\n addedNodes.push(virtualDOMElementToStatic(virtualDOMElement));\n }\n const removedNodeIds = [];\n for (const node of mutation.removedNodes) {\n if (this.isIgnoredElement(node)) {\n continue;\n }\n const virtualDOMElement = this.getVirtualDOMElementForRealElementOrThrow(\n node\n );\n removedNodeIds.push(virtualDOMElement.nodeId);\n }\n const mutationRecord = {\n type: mutation.type,\n targetId: targetElement.nodeId,\n addedNodes,\n removedNodeIds,\n previousSiblingId: firstNonIgnoredPreviousSibling !== null ? this.getVirtualDOMElementForRealElementOrThrow(firstNonIgnoredPreviousSibling).nodeId : null,\n attribute: mutation.attributeName ? {\n attributeName: mutation.attributeName,\n value: mutation.target.getAttribute(mutation.attributeName)\n } : null\n };\n this.callback(\n {\n mutation: mutationRecord,\n documentTime: this.getDocumentTime()\n },\n this\n );\n this.removeKnownNodesInMutation(mutation);\n }\n }\n addKnownNodesInMutation(mutation) {\n const targetNode = mutation.target;\n const virtualDOMElement = this.realElementToVirtualElement.get(targetNode);\n if (!virtualDOMElement) {\n throw new Error(\n "Unknown node in addKnownNodesInMutation:" + targetNode + "," + mutation.type\n );\n }\n if (mutation.type === "childList") {\n let previousSibling = mutation.previousSibling;\n let index = 0;\n while (previousSibling && this.isIgnoredElement(previousSibling)) {\n previousSibling = previousSibling.previousSibling;\n }\n if (previousSibling) {\n const previousSiblingElement = this.realElementToVirtualElement.get(\n previousSibling\n );\n if (!previousSiblingElement) {\n throw new Error("Unknown previous sibling");\n }\n index = virtualDOMElement.childNodes.indexOf(previousSiblingElement);\n if (index === -1) {\n throw new Error("Previous sibling is not currently a child of the parent element");\n }\n index += 1;\n }\n mutation.addedNodes.forEach((node) => {\n const asElementOrText = node;\n const childVirtualDOMElement = this.createVirtualDOMElementWithChildren(\n asElementOrText,\n virtualDOMElement\n );\n if (childVirtualDOMElement) {\n if (virtualDOMElement.childNodes.indexOf(childVirtualDOMElement) === -1) {\n virtualDOMElement.childNodes.splice(index, 0, childVirtualDOMElement);\n index++;\n }\n }\n });\n } else if (mutation.type === "attributes") {\n const attributeName = mutation.attributeName;\n if (this.isIgnoredAttribute(targetNode, attributeName)) {\n return;\n }\n const attributeValue = targetNode.getAttribute(attributeName);\n if (attributeValue === null) {\n delete virtualDOMElement.attributes[attributeName];\n } else {\n virtualDOMElement.attributes[attributeName] = attributeValue;\n }\n } else if (mutation.type === "characterData") {\n virtualDOMElement.textContent = targetNode.textContent ? targetNode.textContent : void 0;\n }\n }\n removeKnownNodesInMutation(mutation) {\n const targetNode = mutation.target;\n const virtualDOMElement = this.realElementToVirtualElement.get(targetNode);\n if (!virtualDOMElement) {\n throw new Error("Unknown node in mutation list:" + targetNode + ", " + mutation.type);\n }\n if (mutation.type === "childList") {\n for (const node of mutation.removedNodes) {\n const asElementOrText = node;\n if (this.isIgnoredElement(asElementOrText)) {\n continue;\n }\n const childDOMElement = this.realElementToVirtualElement.get(asElementOrText);\n if (!childDOMElement) {\n console.warn(this.htmlPath, "Unknown node in removeKnownNodesInMutation");\n continue;\n } else {\n this.removeVirtualDOMElement(childDOMElement);\n const index = virtualDOMElement.childNodes.indexOf(childDOMElement);\n virtualDOMElement.childNodes.splice(index, 1);\n }\n }\n return;\n }\n }\n removeVirtualDOMElement(virtualDOMElement) {\n this.nodeIdToNode.delete(virtualDOMElement.nodeId);\n this.nodeToNodeId.delete(virtualDOMElement);\n this.realElementToVirtualElement.delete(virtualDOMElement.realElement);\n for (const child of virtualDOMElement.childNodes) {\n this.removeVirtualDOMElement(child);\n }\n }\n createVirtualDOMElementWithChildren(node, parent) {\n const virtualElement = this.createVirtualDOMElement(node, parent);\n if (!virtualElement) {\n return null;\n }\n if (node.childNodes) {\n for (let i = 0; i < node.childNodes.length; i++) {\n const child = node.childNodes[i];\n const childVirtualElement = this.createVirtualDOMElementWithChildren(\n child,\n virtualElement\n );\n if (childVirtualElement) {\n virtualElement.childNodes.push(childVirtualElement);\n }\n }\n }\n return virtualElement;\n }\n createVirtualDOMElement(node, parent) {\n if (this.isIgnoredElement(node)) {\n return null;\n }\n const existingValue = this.realElementToVirtualElement.get(node);\n if (existingValue !== void 0) {\n throw new Error("Node already has a virtual element: " + node.nodeName);\n }\n if (!node) {\n throw new Error("Cannot assign node id to null");\n }\n const attributes = {};\n if (node.attributes) {\n const asHTMLElement = node;\n for (const key of asHTMLElement.getAttributeNames()) {\n const value = asHTMLElement.getAttribute(key);\n if (value === null) {\n throw new Error("Null attribute value for key: " + key);\n }\n if (!this.isIgnoredAttribute(node, key)) {\n attributes[key] = value;\n }\n }\n }\n const nodeId = this.nextNodeId++;\n const virtualElement = {\n nodeId,\n tag: node.nodeName,\n attributes,\n childNodes: [],\n realElement: node,\n parent\n };\n if (node instanceof this.domRunner.getWindow().Text && node.textContent) {\n virtualElement.textContent = node.textContent;\n }\n this.nodeToNodeId.set(virtualElement, nodeId);\n this.nodeIdToNode.set(nodeId, virtualElement);\n this.realElementToVirtualElement.set(node, virtualElement);\n return virtualElement;\n }\n getFirstNonIgnoredPreviousSibling(node) {\n let currentNode = node;\n if (!this.isIgnoredElement(currentNode)) {\n return currentNode;\n }\n while (currentNode && currentNode.previousSibling) {\n currentNode = currentNode.previousSibling;\n if (!this.isIgnoredElement(currentNode)) {\n return currentNode;\n }\n }\n return null;\n }\n getVirtualDOMElementForRealElementOrThrow(realElement) {\n const virtualElement = this.realElementToVirtualElement.get(realElement);\n if (!virtualElement) {\n throw new Error(`Virtual element not found for real element`);\n }\n return virtualElement;\n }\n isIgnoredElement(node) {\n if (this.ignoreTextNodes && node instanceof this.domRunner.getWindow().Text) {\n return true;\n } else if (node instanceof this.domRunner.getWindow().HTMLScriptElement) {\n return true;\n } else if (node instanceof this.domRunner.getWindow().Comment) {\n return true;\n }\n return false;\n }\n isIgnoredAttribute(node, attributeName) {\n return attributeName.startsWith("on");\n }\n dispatchRemoteEventFromConnectionId(connectionId, remoteEvent) {\n const domNode = this.nodeIdToNode.get(remoteEvent.nodeId);\n if (!domNode) {\n console.error("Unknown node ID in remote event: " + remoteEvent.nodeId);\n return;\n }\n if (domNode instanceof this.domRunner.getWindow().Text) {\n console.warn("Cannot dispatch remote event to text node");\n return;\n }\n this.domRunner.dispatchRemoteEventFromConnectionId(\n connectionId,\n domNode.realElement,\n remoteEvent\n );\n }\n dispose() {\n clearInterval(this.documentTimeIntervalTimer);\n this.domRunner.dispose();\n }\n getDocumentTime() {\n return this.domRunner.getDocumentTime();\n }\n};\n\n// src/IframeWebRunner.ts\nvar import_observable_dom_common = __toESM(require_build());\n\n// src/WebBrowserDOMRunner.ts\nvar WebBrowserDOMRunnerFactory = (htmlPath, htmlContents, params, callback) => {\n return new WebBrowserDOMRunner(htmlPath, htmlContents, params, callback);\n};\nvar documentLoadTime = Date.now();\nvar WebBrowserDOMRunner = class {\n constructor(htmlPath, htmlContents, params, callback) {\n this.htmlPath = htmlPath;\n this.callback = callback;\n for (const level of ["error", "warn", "info", "log"]) {\n const defaultFn = window.console[level];\n window.console[level] = (...args2) => {\n callback({\n logMessage: {\n level,\n content: args2\n }\n });\n defaultFn(...args2);\n };\n }\n window.onerror = (message, source, line, column, error) => {\n callback({\n logMessage: {\n level: "system",\n content: [\n {\n message,\n type: error == null ? void 0 : error.name,\n line,\n column\n }\n ]\n }\n });\n return false;\n };\n let didSendLoad = false;\n this.mutationObserver = new window.MutationObserver((mutationList) => {\n if (!document) {\n return;\n }\n if (!didSendLoad) {\n throw new Error("MutationObserver called before load");\n }\n this.callback({\n mutationList\n });\n });\n window.params = params;\n const finishLoad = () => {\n if (didSendLoad) {\n throw new Error("finishLoad called twice");\n }\n didSendLoad = true;\n this.callback({\n loaded: true\n });\n this.mutationObserver.observe(window.document, {\n attributes: true,\n childList: true,\n subtree: true,\n characterData: true\n });\n };\n if (document.body) {\n setTimeout(finishLoad, 0);\n } else {\n window.addEventListener("DOMContentLoaded", finishLoad);\n }\n }\n dispatchRemoteEventFromConnectionId(connectionId, realElement, remoteEvent) {\n const bubbles = remoteEvent.bubbles || false;\n const remoteEventObject = new CustomEvent(remoteEvent.name, {\n bubbles,\n detail: __spreadProps(__spreadValues({}, remoteEvent.params), { connectionId })\n });\n realElement.dispatchEvent(remoteEventObject);\n }\n dispose() {\n console.log("WebBrowserDOMRunner.dispose");\n }\n getDocument() {\n return document;\n }\n getDocumentTime() {\n if (document.timeline && document.timeline.currentTime) {\n return document.timeline.currentTime;\n }\n return Date.now() - documentLoadTime;\n }\n // TODO - resolve types (Window needs to expose classes such as CustomEvent as properties)\n getWindow() {\n return window;\n }\n};\n\n// src/IframeWebRunner.ts\nfunction setupIframeWebRunner(argsString) {\n const observableDOMParams = JSON.parse(atob(argsString));\n const sendMessageToHandler = (message) => {\n window.parent.postMessage(JSON.stringify(message), "*");\n };\n const observableDOM = new ObservableDOM(\n __spreadProps(__spreadValues({}, observableDOMParams), {\n htmlContents: ""\n // This must be empty as the contents are assumed to be provided by the srcdoc\n }),\n (observableDOMMessage) => {\n sendMessageToHandler({\n type: import_observable_dom_common.DOM_MESSAGE_TYPE,\n message: observableDOMMessage\n });\n },\n WebBrowserDOMRunnerFactory\n );\n window.addEventListener("message", (e) => {\n const parsed = JSON.parse(e.data);\n switch (parsed.type) {\n case import_observable_dom_common.DISPATCH_REMOTE_EVENT_FROM_CONNECTION_ID_MESSAGE_TYPE:\n observableDOM.dispatchRemoteEventFromConnectionId(parsed.connectionId, parsed.event);\n break;\n case import_observable_dom_common.ADD_CONNECTED_USER_ID_MESSAGE_TYPE:\n observableDOM.addConnectedUserId(parsed.connectionId);\n break;\n case import_observable_dom_common.REMOVE_CONNECTED_USER_ID_MESSAGE_TYPE:\n observableDOM.removeConnectedUserId(parsed.connectionId);\n break;\n default:\n console.error("Unknown message type", parsed);\n }\n });\n}\n\n// src/index.ts\nvar args = window.args;\nsetupIframeWebRunner(args);\n//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vb2JzZXJ2YWJsZS1kb20tY29tbW9uL3NyYy9pbmRleC50cyIsICIuLi8uLi8uLi9vYnNlcnZhYmxlLWRvbS1jb21tb24vc3JjL21lc3NhZ2VzLnRzIiwgIi4uLy4uLy4uL29ic2VydmFibGUtZG9tL3NyYy91dGlscy50cyIsICIuLi8uLi8uLi9vYnNlcnZhYmxlLWRvbS9zcmMvT2JzZXJ2YWJsZURPTS50cyIsICIuLi9zcmMvSWZyYW1lV2ViUnVubmVyLnRzIiwgIi4uL3NyYy9XZWJCcm93c2VyRE9NUnVubmVyLnRzIiwgIi4uL3NyYy9pbmRleC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiZXhwb3J0IHR5cGUgeyBSZW1vdGVFdmVudCB9IGZyb20gXCJAbW1sLWlvL25ldHdvcmtlZC1kb20tcHJvdG9jb2xcIjtcblxuZXhwb3J0ICogZnJvbSBcIi4vT2JzZXJ2YWJsZURPTUludGVyZmFjZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vbWVzc2FnZXNcIjtcbiIsICJpbXBvcnQgeyBSZW1vdGVFdmVudCB9IGZyb20gXCJAbW1sLWlvL25ldHdvcmtlZC1kb20tcHJvdG9jb2xcIjtcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZURPTUludGVyZmFjZSwgT2JzZXJ2YWJsZURPTU1lc3NhZ2UgfSBmcm9tIFwiLi9PYnNlcnZhYmxlRE9NSW50ZXJmYWNlXCI7XG5cbmV4cG9ydCBjb25zdCBBRERfQ09OTkVDVEVEX1VTRVJfSURfTUVTU0FHRV9UWVBFID0gXCJhZGRDb25uZWN0ZWRVc2VySWRcIjtcbmV4cG9ydCBjb25zdCBSRU1PVkVfQ09OTkVDVEVEX1VTRVJfSURfTUVTU0FHRV9UWVBFID0gXCJyZW1vdmVDb25uZWN0ZWRVc2VySWRcIjtcbmV4cG9ydCBjb25zdCBESVNQQVRDSF9SRU1PVEVfRVZFTlRfRlJPTV9DT05ORUNUSU9OX0lEX01FU1NBR0VfVFlQRSA9XG4gIFwiZGlzcGF0Y2hSZW1vdGVFdmVudEZyb21Db25uZWN0aW9uSWRcIjtcbmV4cG9ydCBjb25zdCBET01fTUVTU0FHRV9UWVBFID0gXCJkb21cIjtcblxuZXhwb3J0IHR5cGUgQWRkQ29ubmVjdGVkVXNlcklkTWVzc2FnZSA9IHtcbiAgdHlwZTogdHlwZW9mIEFERF9DT05ORUNURURfVVNFUl9JRF9NRVNTQUdFX1RZUEU7XG4gIGNvbm5lY3Rpb25JZDogbnVtYmVyO1xufTtcblxuZXhwb3J0IHR5cGUgUmVtb3ZlQ29ubmVjdGVkVXNlcklkTWVzc2FnZSA9IHtcbiAgdHlwZTogdHlwZW9mIFJFTU9WRV9DT05ORUNURURfVVNFUl9JRF9NRVNTQUdFX1RZUEU7XG4gIGNvbm5lY3Rpb25JZDogbnVtYmVyO1xufTtcblxuZXhwb3J0IHR5cGUgRGlzcGF0Y2hSZW1vdGVFdmVudEZyb21Db25uZWN0aW9uSWRNZXNzYWdlID0ge1xuICB0eXBlOiB0eXBlb2YgRElTUEFUQ0hfUkVNT1RFX0VWRU5UX0ZST01fQ09OTkVDVElPTl9JRF9NRVNTQUdFX1RZUEU7XG4gIGNvbm5lY3Rpb25JZDogbnVtYmVyO1xuICBldmVudDogUmVtb3RlRXZlbnQ7XG59O1xuXG5leHBvcnQgdHlwZSBUb09ic2VydmFibGVET01JbnN0YW5jZU1lc3NhZ2UgPVxuICB8IEFkZENvbm5lY3RlZFVzZXJJZE1lc3NhZ2VcbiAgfCBSZW1vdmVDb25uZWN0ZWRVc2VySWRNZXNzYWdlXG4gIHwgRGlzcGF0Y2hSZW1vdGVFdmVudEZyb21Db25uZWN0aW9uSWRNZXNzYWdlO1xuXG50eXBlIERPTU1lc3NhZ2UgPSB7XG4gIHR5cGU6IHR5cGVvZiBET01fTUVTU0FHRV9UWVBFO1xuICBtZXNzYWdlOiBPYnNlcnZhYmxlRE9NTWVzc2FnZTtcbn07XG5cbmV4cG9ydCB0eXBlIEZyb21PYnNlcnZhYmxlRE9NSW5zdGFuY2VNZXNzYWdlID0gRE9NTWVzc2FnZTtcblxuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5TWVzc2FnZVRvT2JzZXJ2YWJsZURPTUluc3RhbmNlKFxuICBtZXNzYWdlOiBUb09ic2VydmFibGVET01JbnN0YW5jZU1lc3NhZ2UsXG4gIGluc3RhbmNlOiBPYnNlcnZhYmxlRE9NSW50ZXJmYWNlLFxuKSB7XG4gIGlmIChtZXNzYWdlLnR5cGUgPT09IEFERF9DT05ORUNURURfVVNFUl9JRF9NRVNTQUdFX1RZUEUpIHtcbiAgICBpbnN0YW5jZS5hZGRDb25uZWN0ZWRVc2VySWQobWVzc2FnZS5jb25uZWN0aW9uSWQpO1xuICB9IGVsc2UgaWYgKG1lc3NhZ2UudHlwZSA9PT0gUkVNT1ZFX0NPTk5FQ1RFRF9VU0VSX0lEX01FU1NBR0VfVFlQRSkge1xuICAgIGluc3RhbmNlLnJlbW92ZUNvbm5lY3RlZFVzZXJJZChtZXNzYWdlLmNvbm5lY3Rpb25JZCk7XG4gIH0gZWxzZSBpZiAobWVzc2FnZS50eXBlID09PSBESVNQQVRDSF9SRU1PVEVfRVZFTlRfRlJPTV9DT05ORUNUSU9OX0lEX01FU1NBR0VfVFlQRSkge1xuICAgIGluc3RhbmNlLmRpc3BhdGNoUmVtb3RlRXZlbnRGcm9tQ29ubmVjdGlvbklkKG1lc3NhZ2UuY29ubmVjdGlvbklkLCBtZXNzYWdlLmV2ZW50KTtcbiAgfSBlbHNlIHtcbiAgICBjb25zb2xlLmVycm9yKFwiVW5rbm93biBtZXNzYWdlIHR5cGVcIiwgbWVzc2FnZSk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG9ic2VydmFibGVET01JbnRlcmZhY2VUb01lc3NhZ2VTZW5kZXIoXG4gIHNlbmRlcjogKG1lc3NhZ2U6IFRvT2JzZXJ2YWJsZURPTUluc3RhbmNlTWVzc2FnZSkgPT4gdm9pZCxcbiAgZGlzcG9zZTogKCkgPT4gdm9pZCxcbikge1xuICBjb25zdCByZW1vdGVPYnNlcnZhYmxlRE9NOiBPYnNlcnZhYmxlRE9NSW50ZXJmYWNlID0ge1xuICAgIGFkZENvbm5lY3RlZFVzZXJJZChjb25uZWN0aW9uSWQ6IG51bWJlcik6IHZvaWQge1xuICAgICAgc2VuZGVyKHtcbiAgICAgICAgdHlwZTogQUREX0NPTk5FQ1RFRF9VU0VSX0lEX01FU1NBR0VfVFlQRSxcbiAgICAgICAgY29ubmVjdGlvbklkLFxuICAgICAgfSk7XG4gICAgfSxcbiAgICBkaXNwYXRjaFJlbW90ZUV2ZW50RnJvbUNvbm5lY3Rpb25JZChjb25uZWN0aW9uSWQ6IG51bWJlciwgcmVtb3RlRXZlbnQ6IFJlbW90ZUV2ZW50KTogdm9pZCB7XG4gICAgICBzZW5kZXIoe1xuICAgICAgICB0eXBlOiBESVNQQVRDSF9SRU1PVEVfRVZFTlRfRlJPTV9DT05ORUNUSU9OX0lEX01FU1NBR0VfVFlQRSxcbiAgICAgICAgY29ubmVjdGlvbklkLFxuICAgICAgICBldmVudDogcmVtb3RlRXZlbnQsXG4gICAgICB9KTtcbiAgICB9LFxuICAgIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgICBkaXNwb3NlKCk7XG4gICAgfSxcbiAgICByZW1vdmVDb25uZWN0ZWRVc2VySWQoY29ubmVjdGlvbklkOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgIHNlbmRlcih7XG4gICAgICAgIHR5cGU6IFJFTU9WRV9DT05ORUNURURfVVNFUl9JRF9NRVNTQUdFX1RZUEUsXG4gICAgICAgIGNvbm5lY3Rpb25JZCxcbiAgICAgIH0pO1xuICAgIH0sXG4gIH07XG4gIHJldHVybiByZW1vdGVPYnNlcnZhYmxlRE9NO1xufVxuIiwgImltcG9ydCB7IFN0YXRpY1ZpcnR1YWxET01FbGVtZW50IH0gZnJvbSBcIkBtbWwtaW8vb2JzZXJ2YWJsZS1kb20tY29tbW9uXCI7XG5cbmltcG9ydCB7IExpdmVWaXJ0dWFsRE9NRWxlbWVudCB9IGZyb20gXCIuL09ic2VydmFibGVET01cIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHZpcnR1YWxET01FbGVtZW50VG9TdGF0aWMoZWw6IExpdmVWaXJ0dWFsRE9NRWxlbWVudCk6IFN0YXRpY1ZpcnR1YWxET01FbGVtZW50IHtcbiAgcmV0dXJuIHtcbiAgICBub2RlSWQ6IGVsLm5vZGVJZCxcbiAgICB0YWc6IGVsLnRhZyxcbiAgICBhdHRyaWJ1dGVzOiBlbC5hdHRyaWJ1dGVzLFxuICAgIGNoaWxkTm9kZXM6IGVsLmNoaWxkTm9kZXMubWFwKChjaGlsZCkgPT4gdmlydHVhbERPTUVsZW1lbnRUb1N0YXRpYyhjaGlsZCkpLFxuICAgIHRleHRDb250ZW50OiBlbC50ZXh0Q29udGVudCxcbiAgfTtcbn1cbiIsICJpbXBvcnQge1xuICBMb2dNZXNzYWdlLFxuICBPYnNlcnZhYmxlRE9NSW50ZXJmYWNlLFxuICBPYnNlcnZhYmxlRE9NTWVzc2FnZSxcbiAgT2JzZXJ2YWJsZURPTVBhcmFtZXRlcnMsXG4gIFJlbW90ZUV2ZW50LFxuICBTdGF0aWNWaXJ0dWFsRE9NRWxlbWVudCxcbiAgU3RhdGljVmlydHVhbERPTU11dGF0aW9uSWRzUmVjb3JkLFxufSBmcm9tIFwiQG1tbC1pby9vYnNlcnZhYmxlLWRvbS1jb21tb25cIjtcblxuaW1wb3J0IHsgdmlydHVhbERPTUVsZW1lbnRUb1N0YXRpYyB9IGZyb20gXCIuL3V0aWxzXCI7XG5cbmV4cG9ydCB0eXBlIERPTVJ1bm5lck1lc3NhZ2UgPSB7XG4gIGxvYWRlZD86IGJvb2xlYW47XG4gIG11dGF0aW9uTGlzdD86IEFycmF5PE11dGF0aW9uUmVjb3JkPjtcbiAgbG9nTWVzc2FnZT86IExvZ01lc3NhZ2U7XG59O1xuXG5leHBvcnQgdHlwZSBET01SdW5uZXJJbnRlcmZhY2UgPSB7XG4gIGdldERvY3VtZW50KCk6IERvY3VtZW50O1xuICBnZXRXaW5kb3coKTogV2luZG93ICYge1xuICAgIEN1c3RvbUV2ZW50OiB0eXBlb2YgQ3VzdG9tRXZlbnQ7XG4gICAgVGV4dDogdHlwZW9mIFRleHQ7XG4gICAgSFRNTFNjcmlwdEVsZW1lbnQ6IHR5cGVvZiBIVE1MU2NyaXB0RWxlbWVudDtcbiAgICBDb21tZW50OiB0eXBlb2YgQ29tbWVudDtcbiAgfTsgLy8gVE9ETyAtIERlZmluZSB0aGlzIHdpdGhvdXQgdXNpbmcgSlNET00gdHlwZXNcbiAgZGlzcGF0Y2hSZW1vdGVFdmVudEZyb21Db25uZWN0aW9uSWQoXG4gICAgY29ubmVjdGlvbklkOiBudW1iZXIsXG4gICAgcmVhbEVsZW1lbnQ6IEVsZW1lbnQsXG4gICAgcmVtb3RlRXZlbnQ6IFJlbW90ZUV2ZW50LFxuICApOiB2b2lkO1xuICBkaXNwb3NlKCk6IHZvaWQ7XG4gIGdldERvY3VtZW50VGltZSgpOiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBET01SdW5uZXJGYWN0b3J5ID0gKFxuICBodG1sUGF0aDogc3RyaW5nLFxuICBodG1sQ29udGVudHM6IHN0cmluZyxcbiAgcGFyYW1zOiBvYmplY3QsXG4gIGNhbGxiYWNrOiAoZG9tUnVubmVyTWVzc2FnZTogRE9NUnVubmVyTWVzc2FnZSkgPT4gdm9pZCxcbikgPT4gRE9NUnVubmVySW50ZXJmYWNlO1xuXG5leHBvcnQgdHlwZSBMaXZlVmlydHVhbERPTUVsZW1lbnQgPSBPbWl0PFN0YXRpY1ZpcnR1YWxET01FbGVtZW50LCBcImNoaWxkTm9kZXNcIj4gJiB7XG4gIHJlYWxFbGVtZW50OiBFbGVtZW50IHwgVGV4dDtcbiAgY2hpbGROb2RlczogQXJyYXk8TGl2ZVZpcnR1YWxET01FbGVtZW50PjtcbiAgcGFyZW50OiBMaXZlVmlydHVhbERPTUVsZW1lbnQgfCBudWxsO1xufTtcblxuZXhwb3J0IGNsYXNzIE9ic2VydmFibGVET00gaW1wbGVtZW50cyBPYnNlcnZhYmxlRE9NSW50ZXJmYWNlIHtcbiAgcHJpdmF0ZSBub2RlVG9Ob2RlSWQgPSBuZXcgTWFwPExpdmVWaXJ0dWFsRE9NRWxlbWVudCwgbnVtYmVyPigpO1xuICBwcml2YXRlIG5vZGVJZFRvTm9kZSA9IG5ldyBNYXA8bnVtYmVyLCBMaXZlVmlydHVhbERPTUVsZW1lbnQ+KCk7XG4gIHByaXZhdGUgcmVhbEVsZW1lbnRUb1ZpcnR1YWxFbGVtZW50ID0gbmV3IE1hcDxFbGVtZW50IHwgVGV4dCwgTGl2ZVZpcnR1YWxET01FbGVtZW50PigpO1xuICBwcml2YXRlIGlnbm9yZVRleHROb2RlcyA9IHRydWU7XG4gIHByaXZhdGUgY2FsbGJhY2s6IChtZXNzYWdlOiBPYnNlcnZhYmxlRE9NTWVzc2FnZSwgb2JzZXJ2YWJsZURPTTogT2JzZXJ2YWJsZURPTUludGVyZmFjZSkgPT4gdm9pZDtcbiAgcHJpdmF0ZSBuZXh0Tm9kZUlkID0gMTtcbiAgcHJpdmF0ZSBodG1sUGF0aDogc3RyaW5nO1xuICBwcml2YXRlIGRvbVJ1bm5lcjogRE9NUnVubmVySW50ZXJmYWNlO1xuXG4gIHByaXZhdGUgZG9jdW1lbnRUaW1lSW50ZXJ2YWxUaW1lcjogTm9kZUpTLlRpbWVyO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIG9ic2VydmFibGVET01QYXJhbWV0ZXJzOiBPYnNlcnZhYmxlRE9NUGFyYW1ldGVycyxcbiAgICBjYWxsYmFjazogKG1lc3NhZ2U6IE9ic2VydmFibGVET01NZXNzYWdlLCBvYnNlcnZhYmxlRE9NOiBPYnNlcnZhYmxlRE9NSW50ZXJmYWNlKSA9PiB2b2lkLFxuICAgIHJ1bm5lckZhY3Rvcnk6IERPTVJ1bm5lckZhY3RvcnksXG4gICkge1xuICAgIHRoaXMuaHRtbFBhdGggPSBvYnNlcnZhYmxlRE9NUGFyYW1ldGVycy5odG1sUGF0aDtcbiAgICB0aGlzLmlnbm9yZVRleHROb2RlcyA9IG9ic2VydmFibGVET01QYXJhbWV0ZXJzLmlnbm9yZVRleHROb2RlcztcbiAgICB0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2s7XG5cbiAgICB0aGlzLmRvY3VtZW50VGltZUludGVydmFsVGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICB0aGlzLmNhbGxiYWNrKFxuICAgICAgICB7XG4gICAgICAgICAgZG9jdW1lbnRUaW1lOiB0aGlzLmdldERvY3VtZW50VGltZSgpLFxuICAgICAgICB9LFxuICAgICAgICB0aGlzLFxuICAgICAgKTtcbiAgICB9LCBvYnNlcnZhYmxlRE9NUGFyYW1ldGVycy5waW5nSW50ZXJ2YWxNaWxsaXNlY29uZHMgfHwgNTAwMCk7XG5cbiAgICB0aGlzLmRvbVJ1bm5lciA9IHJ1bm5lckZhY3RvcnkoXG4gICAgICBvYnNlcnZhYmxlRE9NUGFyYW1ldGVycy5odG1sUGF0aCxcbiAgICAgIG9ic2VydmFibGVET01QYXJhbWV0ZXJzLmh0bWxDb250ZW50cyxcbiAgICAgIG9ic2VydmFibGVET01QYXJhbWV0ZXJzLnBhcmFtcyxcbiAgICAgIChkb21SdW5uZXJNZXNzYWdlOiBET01SdW5uZXJNZXNzYWdlKSA9PiB7XG4gICAgICAgIGlmIChkb21SdW5uZXJNZXNzYWdlLmxvYWRlZCkge1xuICAgICAgICAgIHRoaXMuY3JlYXRlVmlydHVhbERPTUVsZW1lbnRXaXRoQ2hpbGRyZW4oXG4gICAgICAgICAgICB0aGlzLmRvbVJ1bm5lci5nZXREb2N1bWVudCgpIGFzIHVua25vd24gYXMgRWxlbWVudCxcbiAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIGNvbnN0IHNuYXBzaG90ID0gdmlydHVhbERPTUVsZW1lbnRUb1N0YXRpYyhcbiAgICAgICAgICAgIHRoaXMuZ2V0VmlydHVhbERPTUVsZW1lbnRGb3JSZWFsRWxlbWVudE9yVGhyb3coXG4gICAgICAgICAgICAgIHRoaXMuZG9tUnVubmVyLmdldERvY3VtZW50KCkgYXMgdW5rbm93biBhcyBFbGVtZW50LFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgdGhpcy5jYWxsYmFjayhcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgc25hcHNob3QsXG4gICAgICAgICAgICAgIGRvY3VtZW50VGltZTogdGhpcy5nZXREb2N1bWVudFRpbWUoKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSBpZiAoZG9tUnVubmVyTWVzc2FnZS5tdXRhdGlvbkxpc3QpIHtcbiAgICAgICAgICB0aGlzLnByb2Nlc3NNb2RpZmljYXRpb25MaXN0KGRvbVJ1bm5lck1lc3NhZ2UubXV0YXRpb25MaXN0KTtcbiAgICAgICAgfSBlbHNlIGlmIChkb21SdW5uZXJNZXNzYWdlLmxvZ01lc3NhZ2UpIHtcbiAgICAgICAgICB0aGlzLmNhbGxiYWNrKFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBsb2dNZXNzYWdlOiBkb21SdW5uZXJNZXNzYWdlLmxvZ01lc3NhZ2UsXG4gICAgICAgICAgICAgIGRvY3VtZW50VGltZTogdGhpcy5nZXREb2N1bWVudFRpbWUoKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB0aGlzLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRDb25uZWN0ZWRVc2VySWQoY29ubmVjdGlvbklkOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmRvbVJ1bm5lci5nZXRXaW5kb3coKS5kaXNwYXRjaEV2ZW50KFxuICAgICAgbmV3ICh0aGlzLmRvbVJ1bm5lci5nZXRXaW5kb3coKS5DdXN0b21FdmVudCkoXCJjb25uZWN0ZWRcIiwge1xuICAgICAgICBkZXRhaWw6IHsgY29ubmVjdGlvbklkIH0sXG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgcHVibGljIHJlbW92ZUNvbm5lY3RlZFVzZXJJZChjb25uZWN0aW9uSWQ6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZG9tUnVubmVyLmdldFdpbmRvdygpLmRpc3BhdGNoRXZlbnQoXG4gICAgICBuZXcgKHRoaXMuZG9tUnVubmVyLmdldFdpbmRvdygpLkN1c3RvbUV2ZW50KShcImRpc2Nvbm5lY3RlZFwiLCB7XG4gICAgICAgIGRldGFpbDogeyBjb25uZWN0aW9uSWQgfSxcbiAgICAgIH0pLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHByb2Nlc3NNb2RpZmljYXRpb25MaXN0KG11dGF0aW9uTGlzdDogQXJyYXk8TXV0YXRpb25SZWNvcmQ+KTogdm9pZCB7XG4gICAgY29uc3QgZG9jdW1lbnRFbCA9IHRoaXMuZG9tUnVubmVyLmdldERvY3VtZW50KCkgYXMgdW5rbm93biBhcyBFbGVtZW50O1xuICAgIGNvbnN0IGRvY3VtZW50VmlydHVhbERPTUVsZW1lbnQgPSB0aGlzLnJlYWxFbGVtZW50VG9WaXJ0dWFsRWxlbWVudC5nZXQoZG9jdW1lbnRFbCk7XG4gICAgaWYgKCFkb2N1bWVudFZpcnR1YWxET01FbGVtZW50KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGRvY3VtZW50IG5vdCBjcmVhdGVkIGluIHByb2Nlc3NNb2RpZmljYXRpb25MaXN0YCk7XG4gICAgfVxuXG4gICAgaWYgKG11dGF0aW9uTGlzdC5sZW5ndGggPiAxKSB7XG4gICAgICAvLyBUT0RPIC0gd2FsayBiYWNrIHRocm91Z2ggdGhlIHJlY29yZHMgdG8gZGVyaXZlIHRoZSBpbnRlcm1lZGlhdGUgc3RhdGVzIChlLmcuIGlmIGFuIGF0dHJpYnV0ZSBpcyBsYXRlciBhZGRlZCB0b1xuICAgICAgLy8gIGFuIGVsZW1lbnQgY3JlYXRlZCBpbiBhbiBlYXJsaWVyIHJlY29yZCB0aGVuIGl0IHNob3VsZCBub3QgaGF2ZSB0aGF0IGF0dHJpYnV0ZSB3aGVuIHRoZSBlbGVtZW50IGlzIGFkZGVkLlxuICAgICAgLy8gIFRoaXMgaXMgaW1wb3J0YW50IGFzIGluY29ycmVjdCBhdHRyaWJ1dGUgc2V0cyBjYW4gYWZmZWN0IHZpc2liaWxpdHkgYW5kIGV4cGVjdGVkIGNsaWVudCBwZXJmb3JtYW5jZS5cbiAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgIFwiTW9yZSB0aGFuIG9uZSBtdXRhdGlvbiByZWNvcmQgcmVjZWl2ZWQuIEl0IGlzIHBvc3NpYmxlIHRoYXQgaW50ZXJtZWRpYXRlIHN0YXRlcyBhcmUgaW5jb3JyZWN0LlwiLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IG11dGF0aW9uIG9mIG11dGF0aW9uTGlzdCkge1xuICAgICAgaWYgKHRoaXMuaXNJZ25vcmVkRWxlbWVudChtdXRhdGlvbi50YXJnZXQgYXMgRWxlbWVudCB8IFRleHQpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIG11dGF0aW9uLnR5cGUgPT09IFwiYXR0cmlidXRlc1wiICYmXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgIHRoaXMuaXNJZ25vcmVkQXR0cmlidXRlKG11dGF0aW9uLnRhcmdldCBhcyBFbGVtZW50IHwgVGV4dCwgbXV0YXRpb24uYXR0cmlidXRlTmFtZSEpXG4gICAgICApIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuYWRkS25vd25Ob2Rlc0luTXV0YXRpb24obXV0YXRpb24pO1xuXG4gICAgICAvLyBDb252ZXJ0IHRoZSBcInJlYWxcIiBET00gTXV0YXRpb25SZWNvcmQgaW50byBhIFwidmlydHVhbFwiIERPTSBNdXRhdGlvblJlY29yZCB0aGF0IHJlZmVyZW5jZXMgdGhlIFZpcnR1YWxET01FbGVtZW50c1xuICAgICAgLy8gVGhpcyBpcyBkb25lIHNvIHRoYXQgdGhlIHNhbWUgcHJvY2VzcyBmb3IgaGFuZGxpbmcgbXV0YXRpb25zIGNhbiBiZSB1c2VkIGZvciBib3RoIGNoYW5nZXMgdG8gYSBsaXZlIERPTSBhbmQgYWxzb1xuICAgICAgLy8gdG8gZGlmZnMgYmV0d2VlbiBET00gc25hcHNob3RzIHdoZW4gcmVsb2FkaW5nXG4gICAgICBjb25zdCBmaXJzdE5vbklnbm9yZWRQcmV2aW91c1NpYmxpbmcgPSBtdXRhdGlvbi5wcmV2aW91c1NpYmxpbmdcbiAgICAgICAgPyB0aGlzLmdldEZpcnN0Tm9uSWdub3JlZFByZXZpb3VzU2libGluZyhtdXRhdGlvbi5wcmV2aW91c1NpYmxpbmcgYXMgRWxlbWVudCB8IFRleHQpXG4gICAgICAgIDogbnVsbDtcbiAgICAgIGNvbnN0IHRhcmdldEVsZW1lbnQgPSB0aGlzLmdldFZpcnR1YWxET01FbGVtZW50Rm9yUmVhbEVsZW1lbnRPclRocm93KFxuICAgICAgICBtdXRhdGlvbi50YXJnZXQgYXMgRWxlbWVudCB8IFRleHQsXG4gICAgICApO1xuICAgICAgY29uc3QgYWRkZWROb2RlczogQXJyYXk8U3RhdGljVmlydHVhbERPTUVsZW1lbnQ+ID0gW107XG4gICAgICBmb3IgKGNvbnN0IG5vZGUgb2YgbXV0YXRpb24uYWRkZWROb2Rlcykge1xuICAgICAgICBpZiAodGhpcy5pc0lnbm9yZWRFbGVtZW50KG5vZGUgYXMgRWxlbWVudCB8IFRleHQpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdmlydHVhbERPTUVsZW1lbnQgPSB0aGlzLmdldFZpcnR1YWxET01FbGVtZW50Rm9yUmVhbEVsZW1lbnRPclRocm93KFxuICAgICAgICAgIG5vZGUgYXMgRWxlbWVudCB8IFRleHQsXG4gICAgICAgICk7XG4gICAgICAgIGFkZGVkTm9kZXMucHVzaCh2aXJ0dWFsRE9NRWxlbWVudFRvU3RhdGljKHZpcnR1YWxET01FbGVtZW50KSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHJlbW92ZWROb2RlSWRzOiBBcnJheTxudW1iZXI+ID0gW107XG4gICAgICBmb3IgKGNvbnN0IG5vZGUgb2YgbXV0YXRpb24ucmVtb3ZlZE5vZGVzKSB7XG4gICAgICAgIGlmICh0aGlzLmlzSWdub3JlZEVsZW1lbnQobm9kZSBhcyBFbGVtZW50IHwgVGV4dCkpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB2aXJ0dWFsRE9NRWxlbWVudCA9IHRoaXMuZ2V0VmlydHVhbERPTUVsZW1lbnRGb3JSZWFsRWxlbWVudE9yVGhyb3coXG4gICAgICAgICAgbm9kZSBhcyBFbGVtZW50IHwgVGV4dCxcbiAgICAgICAgKTtcbiAgICAgICAgcmVtb3ZlZE5vZGVJZHMucHVzaCh2aXJ0dWFsRE9NRWxlbWVudC5ub2RlSWQpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtdXRhdGlvblJlY29yZDogU3RhdGljVmlydHVhbERPTU11dGF0aW9uSWRzUmVjb3JkID0ge1xuICAgICAgICB0eXBlOiBtdXRhdGlvbi50eXBlLFxuICAgICAgICB0YXJnZXRJZDogdGFyZ2V0RWxlbWVudC5ub2RlSWQsXG4gICAgICAgIGFkZGVkTm9kZXMsXG4gICAgICAgIHJlbW92ZWROb2RlSWRzLFxuICAgICAgICBwcmV2aW91c1NpYmxpbmdJZDpcbiAgICAgICAgICBmaXJzdE5vbklnbm9yZWRQcmV2aW91c1NpYmxpbmcgIT09IG51bGxcbiAgICAgICAgICAgID8gdGhpcy5nZXRWaXJ0dWFsRE9NRWxlbWVudEZvclJlYWxFbGVtZW50T3JUaHJvdyhmaXJzdE5vbklnbm9yZWRQcmV2aW91c1NpYmxpbmcpLm5vZGVJZFxuICAgICAgICAgICAgOiBudWxsLFxuICAgICAgICBhdHRyaWJ1dGU6IG11dGF0aW9uLmF0dHJpYnV0ZU5hbWVcbiAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgYXR0cmlidXRlTmFtZTogbXV0YXRpb24uYXR0cmlidXRlTmFtZSxcbiAgICAgICAgICAgICAgdmFsdWU6IChtdXRhdGlvbi50YXJnZXQgYXMgRWxlbWVudCkuZ2V0QXR0cmlidXRlKG11dGF0aW9uLmF0dHJpYnV0ZU5hbWUpLFxuICAgICAgICAgICAgfVxuICAgICAgICAgIDogbnVsbCxcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuY2FsbGJhY2soXG4gICAgICAgIHtcbiAgICAgICAgICBtdXRhdGlvbjogbXV0YXRpb25SZWNvcmQsXG4gICAgICAgICAgZG9jdW1lbnRUaW1lOiB0aGlzLmdldERvY3VtZW50VGltZSgpLFxuICAgICAgICB9LFxuICAgICAgICB0aGlzLFxuICAgICAgKTtcblxuICAgICAgdGhpcy5yZW1vdmVLbm93bk5vZGVzSW5NdXRhdGlvbihtdXRhdGlvbik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhZGRLbm93bk5vZGVzSW5NdXRhdGlvbihtdXRhdGlvbjogTXV0YXRpb25SZWNvcmQpOiB2b2lkIHtcbiAgICBjb25zdCB0YXJnZXROb2RlID0gbXV0YXRpb24udGFyZ2V0IGFzIEVsZW1lbnQgfCBUZXh0O1xuICAgIGNvbnN0IHZpcnR1YWxET01FbGVtZW50ID0gdGhpcy5yZWFsRWxlbWVudFRvVmlydHVhbEVsZW1lbnQuZ2V0KHRhcmdldE5vZGUpO1xuICAgIGlmICghdmlydHVhbERPTUVsZW1lbnQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJVbmtub3duIG5vZGUgaW4gYWRkS25vd25Ob2Rlc0luTXV0YXRpb246XCIgKyB0YXJnZXROb2RlICsgXCIsXCIgKyBtdXRhdGlvbi50eXBlLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKG11dGF0aW9uLnR5cGUgPT09IFwiY2hpbGRMaXN0XCIpIHtcbiAgICAgIGxldCBwcmV2aW91c1NpYmxpbmcgPSBtdXRhdGlvbi5wcmV2aW91c1NpYmxpbmc7XG4gICAgICBsZXQgaW5kZXggPSAwO1xuICAgICAgd2hpbGUgKHByZXZpb3VzU2libGluZyAmJiB0aGlzLmlzSWdub3JlZEVsZW1lbnQocHJldmlvdXNTaWJsaW5nIGFzIEVsZW1lbnQgfCBUZXh0KSkge1xuICAgICAgICBwcmV2aW91c1NpYmxpbmcgPSBwcmV2aW91c1NpYmxpbmcucHJldmlvdXNTaWJsaW5nO1xuICAgICAgfVxuICAgICAgaWYgKHByZXZpb3VzU2libGluZykge1xuICAgICAgICBjb25zdCBwcmV2aW91c1NpYmxpbmdFbGVtZW50ID0gdGhpcy5yZWFsRWxlbWVudFRvVmlydHVhbEVsZW1lbnQuZ2V0KFxuICAgICAgICAgIHByZXZpb3VzU2libGluZyBhcyBFbGVtZW50IHwgVGV4dCxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCFwcmV2aW91c1NpYmxpbmdFbGVtZW50KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBwcmV2aW91cyBzaWJsaW5nXCIpO1xuICAgICAgICB9XG4gICAgICAgIGluZGV4ID0gdmlydHVhbERPTUVsZW1lbnQuY2hpbGROb2Rlcy5pbmRleE9mKHByZXZpb3VzU2libGluZ0VsZW1lbnQpO1xuICAgICAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUHJldmlvdXMgc2libGluZyBpcyBub3QgY3VycmVudGx5IGEgY2hpbGQgb2YgdGhlIHBhcmVudCBlbGVtZW50XCIpO1xuICAgICAgICB9XG4gICAgICAgIGluZGV4ICs9IDE7XG4gICAgICB9XG4gICAgICBtdXRhdGlvbi5hZGRlZE5vZGVzLmZvckVhY2goKG5vZGU6IE5vZGUpID0+IHtcbiAgICAgICAgY29uc3QgYXNFbGVtZW50T3JUZXh0ID0gbm9kZSBhcyBFbGVtZW50IHwgVGV4dDtcbiAgICAgICAgY29uc3QgY2hpbGRWaXJ0dWFsRE9NRWxlbWVudCA9IHRoaXMuY3JlYXRlVmlydHVhbERPTUVsZW1lbnRXaXRoQ2hpbGRyZW4oXG4gICAgICAgICAgYXNFbGVtZW50T3JUZXh0LFxuICAgICAgICAgIHZpcnR1YWxET01FbGVtZW50LFxuICAgICAgICApO1xuICAgICAgICBpZiAoY2hpbGRWaXJ0dWFsRE9NRWxlbWVudCkge1xuICAgICAgICAgIGlmICh2aXJ0dWFsRE9NRWxlbWVudC5jaGlsZE5vZGVzLmluZGV4T2YoY2hpbGRWaXJ0dWFsRE9NRWxlbWVudCkgPT09IC0xKSB7XG4gICAgICAgICAgICB2aXJ0dWFsRE9NRWxlbWVudC5jaGlsZE5vZGVzLnNwbGljZShpbmRleCwgMCwgY2hpbGRWaXJ0dWFsRE9NRWxlbWVudCk7XG4gICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChtdXRhdGlvbi50eXBlID09PSBcImF0dHJpYnV0ZXNcIikge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgIGNvbnN0IGF0dHJpYnV0ZU5hbWUgPSBtdXRhdGlvbi5hdHRyaWJ1dGVOYW1lITtcbiAgICAgIGlmICh0aGlzLmlzSWdub3JlZEF0dHJpYnV0ZSh0YXJnZXROb2RlLCBhdHRyaWJ1dGVOYW1lKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCBhdHRyaWJ1dGVWYWx1ZSA9ICh0YXJnZXROb2RlIGFzIEVsZW1lbnQpLmdldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lKTtcbiAgICAgIGlmIChhdHRyaWJ1dGVWYWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICBkZWxldGUgdmlydHVhbERPTUVsZW1lbnQuYXR0cmlidXRlc1thdHRyaWJ1dGVOYW1lXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZpcnR1YWxET01FbGVtZW50LmF0dHJpYnV0ZXNbYXR0cmlidXRlTmFtZV0gPSBhdHRyaWJ1dGVWYWx1ZTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG11dGF0aW9uLnR5cGUgPT09IFwiY2hhcmFjdGVyRGF0YVwiKSB7XG4gICAgICB2aXJ0dWFsRE9NRWxlbWVudC50ZXh0Q29udGVudCA9IHRhcmdldE5vZGUudGV4dENvbnRlbnQgPyB0YXJnZXROb2RlLnRleHRDb250ZW50IDogdW5kZWZpbmVkO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlS25vd25Ob2Rlc0luTXV0YXRpb24obXV0YXRpb246IE11dGF0aW9uUmVjb3JkKTogdm9pZCB7XG4gICAgY29uc3QgdGFyZ2V0Tm9kZSA9IG11dGF0aW9uLnRhcmdldCBhcyBFbGVtZW50IHwgVGV4dDtcbiAgICBjb25zdCB2aXJ0dWFsRE9NRWxlbWVudCA9IHRoaXMucmVhbEVsZW1lbnRUb1ZpcnR1YWxFbGVtZW50LmdldCh0YXJnZXROb2RlKTtcbiAgICBpZiAoIXZpcnR1YWxET01FbGVtZW50KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIG5vZGUgaW4gbXV0YXRpb24gbGlzdDpcIiArIHRhcmdldE5vZGUgKyBcIiwgXCIgKyBtdXRhdGlvbi50eXBlKTtcbiAgICB9XG4gICAgaWYgKG11dGF0aW9uLnR5cGUgPT09IFwiY2hpbGRMaXN0XCIpIHtcbiAgICAgIGZvciAoY29uc3Qgbm9kZSBvZiBtdXRhdGlvbi5yZW1vdmVkTm9kZXMpIHtcbiAgICAgICAgY29uc3QgYXNFbGVtZW50T3JUZXh0ID0gbm9kZSBhcyBFbGVtZW50IHwgVGV4dDtcbiAgICAgICAgaWYgKHRoaXMuaXNJZ25vcmVkRWxlbWVudChhc0VsZW1lbnRPclRleHQpKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2hpbGRET01FbGVtZW50ID0gdGhpcy5yZWFsRWxlbWVudFRvVmlydHVhbEVsZW1lbnQuZ2V0KGFzRWxlbWVudE9yVGV4dCk7XG4gICAgICAgIGlmICghY2hpbGRET01FbGVtZW50KSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKHRoaXMuaHRtbFBhdGgsIFwiVW5rbm93biBub2RlIGluIHJlbW92ZUtub3duTm9kZXNJbk11dGF0aW9uXCIpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMucmVtb3ZlVmlydHVhbERPTUVsZW1lbnQoY2hpbGRET01FbGVtZW50KTtcbiAgICAgICAgICBjb25zdCBpbmRleCA9IHZpcnR1YWxET01FbGVtZW50LmNoaWxkTm9kZXMuaW5kZXhPZihjaGlsZERPTUVsZW1lbnQpO1xuICAgICAgICAgIHZpcnR1YWxET01FbGVtZW50LmNoaWxkTm9kZXMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlVmlydHVhbERPTUVsZW1lbnQodmlydHVhbERPTUVsZW1lbnQ6IExpdmVWaXJ0dWFsRE9NRWxlbWVudCk6IHZvaWQge1xuICAgIHRoaXMubm9kZUlkVG9Ob2RlLmRlbGV0ZSh2aXJ0dWFsRE9NRWxlbWVudC5ub2RlSWQpO1xuICAgIHRoaXMubm9kZVRvTm9kZUlkLmRlbGV0ZSh2aXJ0dWFsRE9NRWxlbWVudCk7XG4gICAgdGhpcy5yZWFsRWxlbWVudFRvVmlydHVhbEVsZW1lbnQuZGVsZXRlKHZpcnR1YWxET01FbGVtZW50LnJlYWxFbGVtZW50KTtcbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIHZpcnR1YWxET01FbGVtZW50LmNoaWxkTm9kZXMpIHtcbiAgICAgIHRoaXMucmVtb3ZlVmlydHVhbERPTUVsZW1lbnQoY2hpbGQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlVmlydHVhbERPTUVsZW1lbnRXaXRoQ2hpbGRyZW4oXG4gICAgbm9kZTogRWxlbWVudCB8IFRleHQsXG4gICAgcGFyZW50OiBMaXZlVmlydHVhbERPTUVsZW1lbnQgfCBudWxsLFxuICApOiBMaXZlVmlydHVhbERPTUVsZW1lbnQgfCBudWxsIHtcbiAgICBjb25zdCB2aXJ0dWFsRWxlbWVudCA9IHRoaXMuY3JlYXRlVmlydHVhbERPTUVsZW1lbnQobm9kZSwgcGFyZW50KTtcbiAgICBpZiAoIXZpcnR1YWxFbGVtZW50KSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKChub2RlIGFzIEVsZW1lbnQpLmNoaWxkTm9kZXMpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgKG5vZGUgYXMgRWxlbWVudCkuY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBjb25zdCBjaGlsZCA9IChub2RlIGFzIEVsZW1lbnQpLmNoaWxkTm9kZXNbaV07XG4gICAgICAgIGNvbnN0IGNoaWxkVmlydHVhbEVsZW1lbnQgPSB0aGlzLmNyZWF0ZVZpcnR1YWxET01FbGVtZW50V2l0aENoaWxkcmVuKFxuICAgICAgICAgIGNoaWxkIGFzIEVsZW1lbnQgfCBUZXh0LFxuICAgICAgICAgIHZpcnR1YWxFbGVtZW50LFxuICAgICAgICApO1xuICAgICAgICBpZiAoY2hpbGRWaXJ0dWFsRWxlbWVudCkge1xuICAgICAgICAgIHZpcnR1YWxFbGVtZW50LmNoaWxkTm9kZXMucHVzaChjaGlsZFZpcnR1YWxFbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2aXJ0dWFsRWxlbWVudDtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlVmlydHVhbERPTUVsZW1lbnQoXG4gICAgbm9kZTogRWxlbWVudCB8IFRleHQsXG4gICAgcGFyZW50OiBMaXZlVmlydHVhbERPTUVsZW1lbnQgfCBudWxsLFxuICApOiBMaXZlVmlydHVhbERPTUVsZW1lbnQgfCBudWxsIHtcbiAgICBpZiAodGhpcy5pc0lnbm9yZWRFbGVtZW50KG5vZGUpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgZXhpc3RpbmdWYWx1ZSA9IHRoaXMucmVhbEVsZW1lbnRUb1ZpcnR1YWxFbGVtZW50LmdldChub2RlKTtcbiAgICBpZiAoZXhpc3RpbmdWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJOb2RlIGFscmVhZHkgaGFzIGEgdmlydHVhbCBlbGVtZW50OiBcIiArIG5vZGUubm9kZU5hbWUpO1xuICAgIH1cbiAgICBpZiAoIW5vZGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBhc3NpZ24gbm9kZSBpZCB0byBudWxsXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IGF0dHJpYnV0ZXM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7fTtcbiAgICBpZiAoKG5vZGUgYXMgYW55KS5hdHRyaWJ1dGVzKSB7XG4gICAgICBjb25zdCBhc0hUTUxFbGVtZW50ID0gbm9kZSBhcyBIVE1MRWxlbWVudDtcbiAgICAgIGZvciAoY29uc3Qga2V5IG9mIGFzSFRNTEVsZW1lbnQuZ2V0QXR0cmlidXRlTmFtZXMoKSkge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGFzSFRNTEVsZW1lbnQuZ2V0QXR0cmlidXRlKGtleSk7XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk51bGwgYXR0cmlidXRlIHZhbHVlIGZvciBrZXk6IFwiICsga2V5KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMuaXNJZ25vcmVkQXR0cmlidXRlKG5vZGUsIGtleSkpIHtcbiAgICAgICAgICBhdHRyaWJ1dGVzW2tleV0gPSB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IG5vZGVJZCA9IHRoaXMubmV4dE5vZGVJZCsrO1xuICAgIGNvbnN0IHZpcnR1YWxFbGVtZW50OiBMaXZlVmlydHVhbERPTUVsZW1lbnQgPSB7XG4gICAgICBub2RlSWQsXG4gICAgICB0YWc6IG5vZGUubm9kZU5hbWUsXG4gICAgICBhdHRyaWJ1dGVzLFxuICAgICAgY2hpbGROb2RlczogW10sXG4gICAgICByZWFsRWxlbWVudDogbm9kZSxcbiAgICAgIHBhcmVudCxcbiAgICB9O1xuICAgIGlmIChub2RlIGluc3RhbmNlb2YgdGhpcy5kb21SdW5uZXIuZ2V0V2luZG93KCkuVGV4dCAmJiBub2RlLnRleHRDb250ZW50KSB7XG4gICAgICB2aXJ0dWFsRWxlbWVudC50ZXh0Q29udGVudCA9IG5vZGUudGV4dENvbnRlbnQ7XG4gICAgfVxuICAgIHRoaXMubm9kZVRvTm9kZUlkLnNldCh2aXJ0dWFsRWxlbWVudCwgbm9kZUlkKTtcbiAgICB0aGlzLm5vZGVJZFRvTm9kZS5zZXQobm9kZUlkLCB2aXJ0dWFsRWxlbWVudCk7XG4gICAgdGhpcy5yZWFsRWxlbWVudFRvVmlydHVhbEVsZW1lbnQuc2V0KG5vZGUsIHZpcnR1YWxFbGVtZW50KTtcbiAgICByZXR1cm4gdmlydHVhbEVsZW1lbnQ7XG4gIH1cblxuICBwcml2YXRlIGdldEZpcnN0Tm9uSWdub3JlZFByZXZpb3VzU2libGluZyhub2RlOiBFbGVtZW50IHwgVGV4dCk6IEVsZW1lbnQgfCBUZXh0IHwgbnVsbCB7XG4gICAgbGV0IGN1cnJlbnROb2RlID0gbm9kZTtcbiAgICBpZiAoIXRoaXMuaXNJZ25vcmVkRWxlbWVudChjdXJyZW50Tm9kZSkpIHtcbiAgICAgIHJldHVybiBjdXJyZW50Tm9kZTtcbiAgICB9XG4gICAgd2hpbGUgKGN1cnJlbnROb2RlICYmIGN1cnJlbnROb2RlLnByZXZpb3VzU2libGluZykge1xuICAgICAgY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZS5wcmV2aW91c1NpYmxpbmcgYXMgRWxlbWVudCB8IFRleHQ7XG4gICAgICBpZiAoIXRoaXMuaXNJZ25vcmVkRWxlbWVudChjdXJyZW50Tm9kZSkpIHtcbiAgICAgICAgcmV0dXJuIGN1cnJlbnROb2RlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0VmlydHVhbERPTUVsZW1lbnRGb3JSZWFsRWxlbWVudE9yVGhyb3coXG4gICAgcmVhbEVsZW1lbnQ6IEVsZW1lbnQgfCBUZXh0LFxuICApOiBMaXZlVmlydHVhbERPTUVsZW1lbnQge1xuICAgIGNvbnN0IHZpcnR1YWxFbGVtZW50ID0gdGhpcy5yZWFsRWxlbWVudFRvVmlydHVhbEVsZW1lbnQuZ2V0KHJlYWxFbGVtZW50KTtcbiAgICBpZiAoIXZpcnR1YWxFbGVtZW50KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFZpcnR1YWwgZWxlbWVudCBub3QgZm91bmQgZm9yIHJlYWwgZWxlbWVudGApO1xuICAgIH1cbiAgICByZXR1cm4gdmlydHVhbEVsZW1lbnQ7XG4gIH1cblxuICBwcml2YXRlIGlzSWdub3JlZEVsZW1lbnQobm9kZTogRWxlbWVudCB8IFRleHQpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5pZ25vcmVUZXh0Tm9kZXMgJiYgbm9kZSBpbnN0YW5jZW9mIHRoaXMuZG9tUnVubmVyLmdldFdpbmRvdygpLlRleHQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSBpZiAobm9kZSBpbnN0YW5jZW9mIHRoaXMuZG9tUnVubmVyLmdldFdpbmRvdygpLkhUTUxTY3JpcHRFbGVtZW50KSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKG5vZGUgaW5zdGFuY2VvZiB0aGlzLmRvbVJ1bm5lci5nZXRXaW5kb3coKS5Db21tZW50KSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0lnbm9yZWRBdHRyaWJ1dGUobm9kZTogRWxlbWVudCB8IFRleHQsIGF0dHJpYnV0ZU5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBhdHRyaWJ1dGVOYW1lLnN0YXJ0c1dpdGgoXCJvblwiKTtcbiAgfVxuXG4gIHB1YmxpYyBkaXNwYXRjaFJlbW90ZUV2ZW50RnJvbUNvbm5lY3Rpb25JZChjb25uZWN0aW9uSWQ6IG51bWJlciwgcmVtb3RlRXZlbnQ6IFJlbW90ZUV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgZG9tTm9kZSA9IHRoaXMubm9kZUlkVG9Ob2RlLmdldChyZW1vdGVFdmVudC5ub2RlSWQpO1xuICAgIGlmICghZG9tTm9kZSkge1xuICAgICAgY29uc29sZS5lcnJvcihcIlVua25vd24gbm9kZSBJRCBpbiByZW1vdGUgZXZlbnQ6IFwiICsgcmVtb3RlRXZlbnQubm9kZUlkKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZG9tTm9kZSBpbnN0YW5jZW9mIHRoaXMuZG9tUnVubmVyLmdldFdpbmRvdygpLlRleHQpIHtcbiAgICAgIGNvbnNvbGUud2FybihcIkNhbm5vdCBkaXNwYXRjaCByZW1vdGUgZXZlbnQgdG8gdGV4dCBub2RlXCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuZG9tUnVubmVyLmRpc3BhdGNoUmVtb3RlRXZlbnRGcm9tQ29ubmVjdGlvbklkKFxuICAgICAgY29ubmVjdGlvbklkLFxuICAgICAgZG9tTm9kZS5yZWFsRWxlbWVudCBhcyBFbGVtZW50LFxuICAgICAgcmVtb3RlRXZlbnQsXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBkaXNwb3NlKCkge1xuICAgIGNsZWFySW50ZXJ2YWwodGhpcy5kb2N1bWVudFRpbWVJbnRlcnZhbFRpbWVyKTtcbiAgICB0aGlzLmRvbVJ1bm5lci5kaXNwb3NlKCk7XG4gIH1cblxuICBwcml2YXRlIGdldERvY3VtZW50VGltZSgpIHtcbiAgICByZXR1cm4gdGhpcy5kb21SdW5uZXIuZ2V0RG9jdW1lbnRUaW1lKCk7XG4gIH1cbn1cbiIsICJpbXBvcnQgeyBPYnNlcnZhYmxlRE9NIH0gZnJvbSBcIkBtbWwtaW8vb2JzZXJ2YWJsZS1kb20vc3JjL09ic2VydmFibGVET01cIjtcbmltcG9ydCB7XG4gIEFERF9DT05ORUNURURfVVNFUl9JRF9NRVNTQUdFX1RZUEUsXG4gIERJU1BBVENIX1JFTU9URV9FVkVOVF9GUk9NX0NPTk5FQ1RJT05fSURfTUVTU0FHRV9UWVBFLFxuICBET01fTUVTU0FHRV9UWVBFLFxuICBGcm9tT2JzZXJ2YWJsZURPTUluc3RhbmNlTWVzc2FnZSxcbiAgT2JzZXJ2YWJsZURPTU1lc3NhZ2UsXG4gIE9ic2VydmFibGVET01QYXJhbWV0ZXJzLFxuICBSRU1PVkVfQ09OTkVDVEVEX1VTRVJfSURfTUVTU0FHRV9UWVBFLFxuICBUb09ic2VydmFibGVET01JbnN0YW5jZU1lc3NhZ2UsXG59IGZyb20gXCJAbW1sLWlvL29ic2VydmFibGUtZG9tLWNvbW1vblwiO1xuXG5pbXBvcnQgeyBXZWJCcm93c2VyRE9NUnVubmVyRmFjdG9yeSB9IGZyb20gXCIuL1dlYkJyb3dzZXJET01SdW5uZXJcIjtcblxuLy8gVGhpcyBydW5zIGluIHRoZSBpZnJhbWUgdGhhdCB3aWxsIGV4ZWN1dGUgdGhlIGRvY3VtZW50IHNjcmlwdCB0byBzZXR1cCB0aGUgbGlzdGVuaW5nIGZvciBldmVudHMgbWVzc2FnZXNcbmV4cG9ydCBmdW5jdGlvbiBzZXR1cElmcmFtZVdlYlJ1bm5lcihhcmdzU3RyaW5nOiBzdHJpbmcpIHtcbiAgY29uc3Qgb2JzZXJ2YWJsZURPTVBhcmFtcyA9IEpTT04ucGFyc2UoYXRvYihhcmdzU3RyaW5nKSkgYXMgT2JzZXJ2YWJsZURPTVBhcmFtZXRlcnM7XG5cbiAgY29uc3Qgc2VuZE1lc3NhZ2VUb0hhbmRsZXIgPSAobWVzc2FnZTogRnJvbU9ic2VydmFibGVET01JbnN0YW5jZU1lc3NhZ2UpID0+IHtcbiAgICB3aW5kb3cucGFyZW50LnBvc3RNZXNzYWdlKEpTT04uc3RyaW5naWZ5KG1lc3NhZ2UpLCBcIipcIik7XG4gIH07XG5cbiAgY29uc3Qgb2JzZXJ2YWJsZURPTSA9IG5ldyBPYnNlcnZhYmxlRE9NKFxuICAgIHtcbiAgICAgIC4uLm9ic2VydmFibGVET01QYXJhbXMsXG4gICAgICBodG1sQ29udGVudHM6IFwiXCIsIC8vIFRoaXMgbXVzdCBiZSBlbXB0eSBhcyB0aGUgY29udGVudHMgYXJlIGFzc3VtZWQgdG8gYmUgcHJvdmlkZWQgYnkgdGhlIHNyY2RvY1xuICAgIH0sXG4gICAgKG9ic2VydmFibGVET01NZXNzYWdlOiBPYnNlcnZhYmxlRE9NTWVzc2FnZSkgPT4ge1xuICAgICAgc2VuZE1lc3NhZ2VUb0hhbmRsZXIoe1xuICAgICAgICB0eXBlOiBET01fTUVTU0FHRV9UWVBFLFxuICAgICAgICBtZXNzYWdlOiBvYnNlcnZhYmxlRE9NTWVzc2FnZSxcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgV2ViQnJvd3NlckRPTVJ1bm5lckZhY3RvcnksXG4gICk7XG5cbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJtZXNzYWdlXCIsIChlKSA9PiB7XG4gICAgY29uc3QgcGFyc2VkID0gSlNPTi5wYXJzZShlLmRhdGEpIGFzIFRvT2JzZXJ2YWJsZURPTUluc3RhbmNlTWVzc2FnZTtcbiAgICBzd2l0Y2ggKHBhcnNlZC50eXBlKSB7XG4gICAgICBjYXNlIERJU1BBVENIX1JFTU9URV9FVkVOVF9GUk9NX0NPTk5FQ1RJT05fSURfTUVTU0FHRV9UWVBFOlxuICAgICAgICBvYnNlcnZhYmxlRE9NLmRpc3BhdGNoUmVtb3RlRXZlbnRGcm9tQ29ubmVjdGlvbklkKHBhcnNlZC5jb25uZWN0aW9uSWQsIHBhcnNlZC5ldmVudCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBBRERfQ09OTkVDVEVEX1VTRVJfSURfTUVTU0FHRV9UWVBFOlxuICAgICAgICBvYnNlcnZhYmxlRE9NLmFkZENvbm5lY3RlZFVzZXJJZChwYXJzZWQuY29ubmVjdGlvbklkKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFJFTU9WRV9DT05ORUNURURfVVNFUl9JRF9NRVNTQUdFX1RZUEU6XG4gICAgICAgIG9ic2VydmFibGVET00ucmVtb3ZlQ29ubmVjdGVkVXNlcklkKHBhcnNlZC5jb25uZWN0aW9uSWQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJVbmtub3duIG1lc3NhZ2UgdHlwZVwiLCBwYXJzZWQpO1xuICAgIH1cbiAgfSk7XG59XG4iLCAiaW1wb3J0IHsgUmVtb3RlRXZlbnQgfSBmcm9tIFwiQG1tbC1pby9uZXR3b3JrZWQtZG9tLXByb3RvY29sXCI7XG5pbXBvcnQgeyBET01SdW5uZXJGYWN0b3J5LCBET01SdW5uZXJJbnRlcmZhY2UsIERPTVJ1bm5lck1lc3NhZ2UgfSBmcm9tIFwiQG1tbC1pby9vYnNlcnZhYmxlLWRvbVwiO1xuXG5leHBvcnQgY29uc3QgV2ViQnJvd3NlckRPTVJ1bm5lckZhY3Rvcnk6IERPTVJ1bm5lckZhY3RvcnkgPSAoXG4gIGh0bWxQYXRoOiBzdHJpbmcsXG4gIGh0bWxDb250ZW50czogc3RyaW5nLFxuICBwYXJhbXM6IG9iamVjdCxcbiAgY2FsbGJhY2s6IChtdXRhdGlvbkxpc3Q6IERPTVJ1bm5lck1lc3NhZ2UpID0+IHZvaWQsXG4pOiBET01SdW5uZXJJbnRlcmZhY2UgPT4ge1xuICByZXR1cm4gbmV3IFdlYkJyb3dzZXJET01SdW5uZXIoaHRtbFBhdGgsIGh0bWxDb250ZW50cywgcGFyYW1zLCBjYWxsYmFjayk7XG59O1xuXG5jb25zdCBkb2N1bWVudExvYWRUaW1lID0gRGF0ZS5ub3coKTtcblxuZXhwb3J0IGNsYXNzIFdlYkJyb3dzZXJET01SdW5uZXIgaW1wbGVtZW50cyBET01SdW5uZXJJbnRlcmZhY2Uge1xuICBwcml2YXRlIG11dGF0aW9uT2JzZXJ2ZXI6IE11dGF0aW9uT2JzZXJ2ZXI7XG4gIHByaXZhdGUgaHRtbFBhdGg6IHN0cmluZztcbiAgcHJpdmF0ZSBjYWxsYmFjazogKGRvbVJ1bm5lck1lc3NhZ2U6IERPTVJ1bm5lck1lc3NhZ2UpID0+IHZvaWQ7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgaHRtbFBhdGg6IHN0cmluZyxcbiAgICBodG1sQ29udGVudHM6IHN0cmluZyxcbiAgICBwYXJhbXM6IG9iamVjdCxcbiAgICBjYWxsYmFjazogKGRvbVJ1bm5lck1lc3NhZ2U6IERPTVJ1bm5lck1lc3NhZ2UpID0+IHZvaWQsXG4gICkge1xuICAgIHRoaXMuaHRtbFBhdGggPSBodG1sUGF0aDtcbiAgICB0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2s7XG5cbiAgICAvLyBGb3J3YXJkIGNvbnNvbGUgbWVzc2FnZXNcbiAgICBmb3IgKGNvbnN0IGxldmVsIG9mIFtcImVycm9yXCIsIFwid2FyblwiLCBcImluZm9cIiwgXCJsb2dcIl0gYXMgY29uc3QpIHtcbiAgICAgIGNvbnN0IGRlZmF1bHRGbiA9IHdpbmRvdy5jb25zb2xlW2xldmVsXTtcblxuICAgICAgd2luZG93LmNvbnNvbGVbbGV2ZWxdID0gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgY2FsbGJhY2soe1xuICAgICAgICAgIGxvZ01lc3NhZ2U6IHtcbiAgICAgICAgICAgIGxldmVsLFxuICAgICAgICAgICAgY29udGVudDogYXJncyxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgZGVmYXVsdEZuKC4uLmFyZ3MpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBGb3J3YXJkIHVuY2F1Z2h0IGVycm9yc1xuICAgIHdpbmRvdy5vbmVycm9yID0gKG1lc3NhZ2UsIHNvdXJjZSwgbGluZSwgY29sdW1uLCBlcnJvcikgPT4ge1xuICAgICAgY2FsbGJhY2soe1xuICAgICAgICBsb2dNZXNzYWdlOiB7XG4gICAgICAgICAgbGV2ZWw6IFwic3lzdGVtXCIsXG4gICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBtZXNzYWdlLFxuICAgICAgICAgICAgICB0eXBlOiBlcnJvcj8ubmFtZSxcbiAgICAgICAgICAgICAgbGluZSxcbiAgICAgICAgICAgICAgY29sdW1uLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIGxldCBkaWRTZW5kTG9hZCA9IGZhbHNlO1xuXG4gICAgdGhpcy5tdXRhdGlvbk9ic2VydmVyID0gbmV3IHdpbmRvdy5NdXRhdGlvbk9ic2VydmVyKChtdXRhdGlvbkxpc3QpID0+IHtcbiAgICAgIGlmICghZG9jdW1lbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKCFkaWRTZW5kTG9hZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNdXRhdGlvbk9ic2VydmVyIGNhbGxlZCBiZWZvcmUgbG9hZFwiKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2FsbGJhY2soe1xuICAgICAgICBtdXRhdGlvbkxpc3QsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgICh3aW5kb3cgYXMgYW55KS5wYXJhbXMgPSBwYXJhbXM7XG5cbiAgICBjb25zdCBmaW5pc2hMb2FkID0gKCkgPT4ge1xuICAgICAgaWYgKGRpZFNlbmRMb2FkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcImZpbmlzaExvYWQgY2FsbGVkIHR3aWNlXCIpO1xuICAgICAgfVxuICAgICAgZGlkU2VuZExvYWQgPSB0cnVlO1xuICAgICAgdGhpcy5jYWxsYmFjayh7XG4gICAgICAgIGxvYWRlZDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5tdXRhdGlvbk9ic2VydmVyLm9ic2VydmUod2luZG93LmRvY3VtZW50LCB7XG4gICAgICAgIGF0dHJpYnV0ZXM6IHRydWUsXG4gICAgICAgIGNoaWxkTGlzdDogdHJ1ZSxcbiAgICAgICAgc3VidHJlZTogdHJ1ZSxcbiAgICAgICAgY2hhcmFjdGVyRGF0YTogdHJ1ZSxcbiAgICAgIH0pO1xuICAgIH07XG4gICAgaWYgKGRvY3VtZW50LmJvZHkpIHtcbiAgICAgIHNldFRpbWVvdXQoZmluaXNoTG9hZCwgMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiRE9NQ29udGVudExvYWRlZFwiLCBmaW5pc2hMb2FkKTtcbiAgICB9XG4gIH1cblxuICBkaXNwYXRjaFJlbW90ZUV2ZW50RnJvbUNvbm5lY3Rpb25JZChcbiAgICBjb25uZWN0aW9uSWQ6IG51bWJlcixcbiAgICByZWFsRWxlbWVudDogRWxlbWVudCxcbiAgICByZW1vdGVFdmVudDogUmVtb3RlRXZlbnQsXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IGJ1YmJsZXMgPSByZW1vdGVFdmVudC5idWJibGVzIHx8IGZhbHNlO1xuICAgIGNvbnN0IHJlbW90ZUV2ZW50T2JqZWN0ID0gbmV3IEN1c3RvbUV2ZW50KHJlbW90ZUV2ZW50Lm5hbWUsIHtcbiAgICAgIGJ1YmJsZXMsXG4gICAgICBkZXRhaWw6IHsgLi4ucmVtb3RlRXZlbnQucGFyYW1zLCBjb25uZWN0aW9uSWQgfSxcbiAgICB9KTtcblxuICAgIC8vIERpc3BhdGNoIHRoZSBldmVudCB2aWEgSmF2YVNjcmlwdC5cbiAgICByZWFsRWxlbWVudC5kaXNwYXRjaEV2ZW50KHJlbW90ZUV2ZW50T2JqZWN0KTtcbiAgfVxuXG4gIGRpc3Bvc2UoKTogdm9pZCB7XG4gICAgLy8gVE9ETyAtIGhhbmRsZSBkaXNwb3NlXG4gICAgY29uc29sZS5sb2coXCJXZWJCcm93c2VyRE9NUnVubmVyLmRpc3Bvc2VcIik7XG4gIH1cblxuICBnZXREb2N1bWVudCgpOiBEb2N1bWVudCB7XG4gICAgcmV0dXJuIGRvY3VtZW50O1xuICB9XG5cbiAgZ2V0RG9jdW1lbnRUaW1lKCk6IG51bWJlciB7XG4gICAgaWYgKGRvY3VtZW50LnRpbWVsaW5lICYmIGRvY3VtZW50LnRpbWVsaW5lLmN1cnJlbnRUaW1lKSB7XG4gICAgICByZXR1cm4gZG9jdW1lbnQudGltZWxpbmUuY3VycmVudFRpbWU7XG4gICAgfVxuICAgIHJldHVybiBEYXRlLm5vdygpIC0gZG9jdW1lbnRMb2FkVGltZTtcbiAgfVxuXG4gIC8vIFRPRE8gLSByZXNvbHZlIHR5cGVzIChXaW5kb3cgbmVlZHMgdG8gZXhwb3NlIGNsYXNzZXMgc3VjaCBhcyBDdXN0b21FdmVudCBhcyBwcm9wZXJ0aWVzKVxuICBnZXRXaW5kb3coKTogYW55IHtcbiAgICByZXR1cm4gd2luZG93O1xuICB9XG59XG4iLCAiaW1wb3J0IHsgc2V0dXBJZnJhbWVXZWJSdW5uZXIgfSBmcm9tIFwiLi9JZnJhbWVXZWJSdW5uZXJcIjtcblxuY29uc3QgYXJncyA9ICh3aW5kb3cgYXMgYW55KS5hcmdzO1xuc2V0dXBJZnJhbWVXZWJSdW5uZXIoYXJncyk7XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxRQUFBLGNBQUEsQ0FBQTtBQUFBLGFBQUEsYUFBQTtNQUFBLG9DQUFBLE1BQUFBO01BQUEsdURBQUEsTUFBQUM7TUFBQSxrQkFBQSxNQUFBQztNQUFBLHVDQUFBLE1BQUFDO01BQUEscUNBQUEsTUFBQTtNQUFBLHVDQUFBLE1BQUE7SUFBQSxDQUFBO0FBQUEsSUFBQUMsUUFBQSxVQUFBLGFBQUEsV0FBQTtBQ0lPLFFBQU1KLHNDQUFxQztBQUMzQyxRQUFNRyx5Q0FBd0M7QUFDOUMsUUFBTUYseURBQ1g7QUFDSyxRQUFNQyxvQkFBbUI7QUE4QnpCLGFBQVMsb0NBQ2QsU0FDQSxVQUNBO0FBQ0EsVUFBSSxRQUFRLFNBQVNGLHFDQUFvQztBQUN2RCxpQkFBUyxtQkFBbUIsUUFBUSxZQUFZO01BQ2xELFdBQVcsUUFBUSxTQUFTRyx3Q0FBdUM7QUFDakUsaUJBQVMsc0JBQXNCLFFBQVEsWUFBWTtNQUNyRCxXQUFXLFFBQVEsU0FBU0Ysd0RBQXVEO0FBQ2pGLGlCQUFTLG9DQUFvQyxRQUFRLGNBQWMsUUFBUSxLQUFLO01BQ2xGLE9BQU87QUFDTCxnQkFBUSxNQUFNLHdCQUF3QixPQUFP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c0IsS0FBSyxNQUFNLEtBQUssVUFBVSxDQUFDO0FBRXZELFFBQU0sdUJBQXVCLENBQUMsWUFBOEM7QUFDMUUsV0FBTyxPQUFPLFlBQVksS0FBSyxVQUFVLE9BQU8sR0FBRyxHQUFHO0FBQUEsRUFDeEQ7QUFFQSxRQUFNLGdCQUFnQixJQUFJO0FBQUEsSUFDeEIsaUNBQ0ssc0JBREw7QUFBQSxNQUVFLGNBQWM7QUFBQTtBQUFBLElBQ2hCO0FBQUEsSUFDQSxDQUFDLHlCQUErQztBQUM5QywyQkFBcUI7QUFBQSxRQUNuQixNQUFNO0FBQUEsUUFDTixTQUFTO0FBQUEsTUFDWCxDQUFDO0FBQUEsSUFDSDtBQUFBLElBQ0E7QUFBQSxFQUNGO0FBRUEsU0FBTyxpQkFBaUIsV0FBVyxDQUFDLE1BQU07QUFDeEMsVUFBTSxTQUFTLEtBQUssTUFBTSxFQUFFLElBQUk7QUFDaEMsWUFBUSxPQUFPLE1BQU07QUFBQSxNQUNuQixLQUFLO0FBQ0gsc0JBQWMsb0NBQW9DLE9BQU8sY0FBYyxPQUFPLEtBQUs7QUFDbkY7QUFBQSxNQUNGLEtBQUs7QUFDSCxzQkFBYyxtQkFBbUIsT0FBTyxZQUFZO0FBQ3BEO0FBQUEsTUFDRixLQUFLO0FBQ0gsc0JBQWMsc0JBQXNCLE9BQU8sWUFBWTtBQUN2RDtBQUFBLE1BQ0Y7QUFDRSxnQkFBUSxNQUFNLHdCQUF3QixNQUFNO0FBQUEsSUFDaEQ7QUFBQSxFQUNGLENBQUM7QUFDSDs7O0FFbERBLElBQU0sT0FBUSxPQUFlO0FBQzdCLHFCQUFxQixJQUFJOyIsCiAgIm5hbWVzIjogWyJBRERfQ09OTkVDVEVEX1VTRVJfSURfTUVTU0FHRV9UWVBFIiwgIkRJU1BBVENIX1JFTU9URV9FVkVOVF9GUk9NX0NPTk5FQ1RJT05fSURfTUVTU0FHRV9UWVBFIiwgIkRPTV9NRVNTQUdFX1RZUEUiLCAiUkVNT1ZFX0NPTk5FQ1RFRF9VU0VSX0lEX01FU1NBR0VfVFlQRSIsICJtb2R1bGUiLCAiYXJncyJdCn0K\n';
|
|
33
33
|
|
|
34
34
|
// src/RunnerIframe.ts
|
|
35
35
|
var RunnerIframe = class {
|
|
@@ -197,42 +197,28 @@ var NetworkedDOMWebRunnerClient = class {
|
|
|
197
197
|
};
|
|
198
198
|
|
|
199
199
|
// src/IframeObservableDOMFactory.ts
|
|
200
|
+
var import_observable_dom_common = require("@mml-io/observable-dom-common");
|
|
200
201
|
var IframeObservableDOMFactory = (observableDOMParameters, callback) => {
|
|
201
202
|
const runnerIframe = new RunnerIframe(
|
|
202
203
|
observableDOMParameters,
|
|
203
|
-
(
|
|
204
|
-
|
|
205
|
-
|
|
204
|
+
(message) => {
|
|
205
|
+
switch (message.type) {
|
|
206
|
+
case import_observable_dom_common.DOM_MESSAGE_TYPE:
|
|
207
|
+
callback(message.message, remoteObservableDOM);
|
|
208
|
+
break;
|
|
209
|
+
default:
|
|
210
|
+
console.error("Unknown message type", message.type);
|
|
206
211
|
}
|
|
207
212
|
}
|
|
208
213
|
);
|
|
209
|
-
const remoteObservableDOM =
|
|
210
|
-
|
|
211
|
-
runnerIframe.sendMessageToRunner(
|
|
212
|
-
type: "addConnectedUserId",
|
|
213
|
-
connectionId
|
|
214
|
-
});
|
|
215
|
-
},
|
|
216
|
-
addIPCWebsocket() {
|
|
217
|
-
throw new Error("Not implemented");
|
|
218
|
-
},
|
|
219
|
-
dispatchRemoteEventFromConnectionId(connectionId, remoteEvent) {
|
|
220
|
-
runnerIframe.sendMessageToRunner({
|
|
221
|
-
type: "dispatchRemoteEventFromConnectionId",
|
|
222
|
-
connectionId,
|
|
223
|
-
event: remoteEvent
|
|
224
|
-
});
|
|
214
|
+
const remoteObservableDOM = (0, import_observable_dom_common.observableDOMInterfaceToMessageSender)(
|
|
215
|
+
(message) => {
|
|
216
|
+
runnerIframe.sendMessageToRunner(message);
|
|
225
217
|
},
|
|
226
|
-
|
|
218
|
+
() => {
|
|
227
219
|
runnerIframe.dispose();
|
|
228
|
-
},
|
|
229
|
-
removeConnectedUserId(connectionId) {
|
|
230
|
-
runnerIframe.sendMessageToRunner({
|
|
231
|
-
type: "removeConnectedUserId",
|
|
232
|
-
connectionId
|
|
233
|
-
});
|
|
234
220
|
}
|
|
235
|
-
|
|
221
|
+
);
|
|
236
222
|
return remoteObservableDOM;
|
|
237
223
|
};
|
|
238
224
|
// Annotate the CommonJS export names for ESM import in node:
|
package/build/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts", "../src/RunnerIframe.ts", "../src/NetworkedDOMWebRunnerClient.ts", "../src/FakeWebsocket.ts", "../src/IframeObservableDOMFactory.ts"],
|
|
4
|
-
"sourcesContent": ["export * from \"@mml-io/networked-dom-document\";\
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAc,2CAAd;;;;;;
|
|
4
|
+
"sourcesContent": ["export * from \"@mml-io/networked-dom-document\";\nexport * from \"./RunnerIframe\";\nexport * from \"./NetworkedDOMWebRunnerClient\";\nexport * from \"./FakeWebsocket\";\nexport * from \"./IframeObservableDOMFactory\";\n", "import {\n FromObservableDOMInstanceMessage,\n ObservableDOMParameters,\n ToObservableDOMInstanceMessage,\n} from \"@mml-io/observable-dom-common\";\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-ignore\n// eslint-disable-next-line import/no-unresolved\nimport runnerText from \"runner-iframe-js-text\";\n\nexport class RunnerIframe {\n private iframe: HTMLIFrameElement;\n private onMessageCallback: (message: FromObservableDOMInstanceMessage) => void;\n private postMessageListener: (messageEvent: MessageEvent) => void;\n\n constructor(\n observableDOMParameters: ObservableDOMParameters,\n onMessageCallback: (message: FromObservableDOMInstanceMessage) => void,\n ) {\n this.iframe = document.createElement(\"iframe\");\n this.iframe.setAttribute(\"sandbox\", \"allow-scripts\");\n this.iframe.style.position = \"fixed\";\n this.iframe.style.top = \"0\";\n this.iframe.style.left = \"0\";\n this.iframe.style.width = \"0\";\n this.iframe.style.height = \"0\";\n this.iframe.style.border = \"none\";\n\n const paramsMinusCode: Partial<ObservableDOMParameters> = {\n ...observableDOMParameters,\n };\n delete paramsMinusCode.htmlContents;\n\n const args = btoa(JSON.stringify(paramsMinusCode));\n\n const isJSDOM = navigator.userAgent.includes(\"jsdom\");\n if (isJSDOM) {\n // srcdoc not supported, so we have to append elements to the iframe's document\n document.body.append(this.iframe);\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const iframeBody = this.iframe.contentWindow!.document.body;\n const argsScriptElement = document.createElement(\"script\");\n argsScriptElement.innerHTML = `window.args=\"${args}\";`;\n iframeBody.append(argsScriptElement);\n const runnerScriptElement = document.createElement(\"script\");\n runnerScriptElement.innerHTML = runnerText;\n iframeBody.append(runnerScriptElement);\n const contentHolder = document.createElement(\"div\");\n iframeBody.append(contentHolder);\n contentHolder.innerHTML = observableDOMParameters.htmlContents;\n } else {\n this.iframe.setAttribute(\n \"srcdoc\",\n `\n <script>window.args=\"${args}\";</script>\n <script>${runnerText}</script>\n ${observableDOMParameters.htmlContents}\n `,\n );\n document.body.append(this.iframe);\n }\n\n this.onMessageCallback = onMessageCallback;\n\n this.postMessageListener = (e: MessageEvent) => {\n if (e.source === this.iframe.contentWindow || (isJSDOM && e.source === null)) {\n const parsed = JSON.parse(e.data) as FromObservableDOMInstanceMessage;\n onMessageCallback(parsed);\n }\n };\n window.addEventListener(\"message\", this.postMessageListener);\n }\n\n sendMessageToRunner(message: ToObservableDOMInstanceMessage) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.iframe.contentWindow!.postMessage(JSON.stringify(message), \"*\");\n }\n\n dispose() {\n window.removeEventListener(\"message\", this.postMessageListener);\n this.iframe.remove();\n }\n}\n", "import { EditableNetworkedDOM, NetworkedDOM } from \"@mml-io/networked-dom-document\";\nimport { NetworkedDOMWebsocket } from \"@mml-io/networked-dom-web\";\n\nimport { FakeWebsocket } from \"./FakeWebsocket\";\n\nexport class NetworkedDOMWebRunnerClient {\n public readonly element: HTMLDivElement;\n protected remoteDocumentHolder: HTMLElement;\n\n protected connectedState: {\n document: NetworkedDOM | EditableNetworkedDOM;\n domWebsocket: NetworkedDOMWebsocket;\n fakeWebsocket: FakeWebsocket;\n } | null = null;\n private enableEventHandling: boolean;\n\n constructor(enableEventHandling = true) {\n this.enableEventHandling = enableEventHandling;\n this.element = document.createElement(\"div\");\n this.element.style.position = \"relative\";\n this.element.style.width = \"100%\";\n this.element.style.height = \"100%\";\n\n this.remoteDocumentHolder = document.createElement(\"div\");\n this.element.append(this.remoteDocumentHolder);\n }\n\n public disconnect() {\n if (!this.connectedState) {\n return;\n }\n this.connectedState.document.removeWebSocket(\n this.connectedState.fakeWebsocket.serverSideWebsocket as unknown as WebSocket,\n );\n this.connectedState = null;\n }\n\n public dispose() {\n this.disconnect();\n this.remoteDocumentHolder.remove();\n this.element.remove();\n }\n\n public connect(\n document: NetworkedDOM | EditableNetworkedDOM,\n timeCallback?: (time: number) => void,\n ) {\n if (this.connectedState) {\n this.disconnect();\n }\n const fakeWebsocket = new FakeWebsocket(\"networked-dom-v0.1\");\n let overriddenHandler: ((element: HTMLElement, event: CustomEvent) => void) | null = null;\n const eventHandler = (element: HTMLElement, event: CustomEvent) => {\n if (!overriddenHandler) {\n throw new Error(\"overriddenHandler not set\");\n }\n overriddenHandler(element, event);\n };\n\n if (this.enableEventHandling) {\n this.remoteDocumentHolder.addEventListener(\"click\", (event: Event) => {\n eventHandler(event.target as HTMLElement, event as CustomEvent);\n event.stopPropagation();\n event.preventDefault();\n return false;\n });\n }\n\n const domWebsocket = new NetworkedDOMWebsocket(\n \"ws://localhost\",\n () => fakeWebsocket.clientSideWebsocket as unknown as WebSocket,\n this.remoteDocumentHolder,\n timeCallback,\n );\n overriddenHandler = (element: HTMLElement, event: CustomEvent) => {\n domWebsocket.handleEvent(element, event);\n };\n document.addWebSocket(fakeWebsocket.serverSideWebsocket as unknown as WebSocket);\n this.connectedState = {\n document,\n fakeWebsocket,\n domWebsocket,\n };\n }\n}\n", "class WebsocketEnd extends EventTarget {\n private readonly sendCallback: (data: string | ArrayBufferLike | Blob | ArrayBufferView) => void;\n public readonly protocol: string;\n\n constructor(\n protocol: string,\n sendCallback: (data: string | ArrayBufferLike | Blob | ArrayBufferView) => void,\n ) {\n super();\n this.protocol = protocol;\n this.sendCallback = sendCallback;\n }\n\n public close() {\n this.dispatchEvent(new CloseEvent(\"close\"));\n }\n\n public addEventListener<K extends keyof WebSocketEventMap>(\n type: K,\n listener: (this: WebSocket, ev: WebSocketEventMap[K]) => any,\n options?: boolean | AddEventListenerOptions,\n ) {\n if (type === \"open\") {\n listener.bind(this)(new Event(\"open\"));\n return;\n }\n super.addEventListener(type, listener, options);\n }\n\n public send(data: string | ArrayBufferLike | Blob | ArrayBufferView) {\n this.sendCallback(data);\n }\n}\n\nexport class FakeWebsocket {\n public clientSideWebsocket: WebsocketEnd;\n public serverSideWebsocket: WebsocketEnd;\n\n constructor(protocol: string) {\n this.clientSideWebsocket = new WebsocketEnd(protocol, (data) => {\n this.serverSideWebsocket.dispatchEvent(\n new MessageEvent(\"message\", {\n data,\n }),\n );\n });\n\n this.serverSideWebsocket = new WebsocketEnd(protocol, (data) => {\n this.clientSideWebsocket.dispatchEvent(\n new MessageEvent(\"message\", {\n data,\n }),\n );\n });\n }\n}\n", "import { ObservableDOMFactory } from \"@mml-io/networked-dom-document\";\nimport {\n DOM_MESSAGE_TYPE,\n FromObservableDOMInstanceMessage,\n ObservableDOMInterface,\n observableDOMInterfaceToMessageSender,\n ObservableDOMMessage,\n ObservableDOMParameters,\n ToObservableDOMInstanceMessage,\n} from \"@mml-io/observable-dom-common\";\n\nimport { RunnerIframe } from \"./RunnerIframe\";\n\nexport const IframeObservableDOMFactory: ObservableDOMFactory = (\n observableDOMParameters: ObservableDOMParameters,\n callback: (message: ObservableDOMMessage, observableDOM: ObservableDOMInterface) => void,\n) => {\n const runnerIframe = new RunnerIframe(\n observableDOMParameters,\n (message: FromObservableDOMInstanceMessage) => {\n switch (message.type) {\n case DOM_MESSAGE_TYPE:\n callback(message.message, remoteObservableDOM);\n break;\n default:\n console.error(\"Unknown message type\", message.type);\n }\n },\n );\n\n const remoteObservableDOM: ObservableDOMInterface = observableDOMInterfaceToMessageSender(\n (message: ToObservableDOMInstanceMessage) => {\n runnerIframe.sendMessageToRunner(message);\n },\n () => {\n runnerIframe.dispose();\n },\n );\n return remoteObservableDOM;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["document"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mml-io/networked-dom-web-runner",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"main": "./build/index.js",
|
|
5
5
|
"types": "./build/index.d.ts",
|
|
6
6
|
"files": [
|
|
@@ -18,14 +18,13 @@
|
|
|
18
18
|
"test-iterate": "jest --watch"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@mml-io/networked-dom-web": "^0.
|
|
21
|
+
"@mml-io/networked-dom-web": "^0.2.0",
|
|
22
|
+
"@mml-io/observable-dom-common": "^0.2.0"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
24
25
|
"@mml-io/networked-dom-web-runner-iframe": "file:../networked-dom-web-runner-iframe",
|
|
25
|
-
"@types/three": "0.152.1",
|
|
26
26
|
"jest-canvas-mock": "2.5.1",
|
|
27
27
|
"jest-environment-jsdom": "29.5.0",
|
|
28
|
-
"jest-expect-message": "1.1.3"
|
|
29
|
-
"standardized-audio-context-mock": "9.6.24"
|
|
28
|
+
"jest-expect-message": "1.1.3"
|
|
30
29
|
}
|
|
31
30
|
}
|
|
@@ -1,53 +1,40 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ObservableDOMFactory } from "@mml-io/networked-dom-document";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
DOM_MESSAGE_TYPE,
|
|
4
|
+
FromObservableDOMInstanceMessage,
|
|
5
|
+
ObservableDOMInterface,
|
|
6
|
+
observableDOMInterfaceToMessageSender,
|
|
7
|
+
ObservableDOMMessage,
|
|
5
8
|
ObservableDOMParameters,
|
|
6
|
-
|
|
9
|
+
ToObservableDOMInstanceMessage,
|
|
7
10
|
} from "@mml-io/observable-dom-common";
|
|
8
11
|
|
|
9
|
-
import { FromInstanceMessageTypes } from "./message-types";
|
|
10
12
|
import { RunnerIframe } from "./RunnerIframe";
|
|
11
13
|
|
|
12
|
-
export const IframeObservableDOMFactory:
|
|
14
|
+
export const IframeObservableDOMFactory: ObservableDOMFactory = (
|
|
13
15
|
observableDOMParameters: ObservableDOMParameters,
|
|
14
|
-
callback: (message:
|
|
16
|
+
callback: (message: ObservableDOMMessage, observableDOM: ObservableDOMInterface) => void,
|
|
15
17
|
) => {
|
|
16
18
|
const runnerIframe = new RunnerIframe(
|
|
17
19
|
observableDOMParameters,
|
|
18
|
-
(
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
(message: FromObservableDOMInstanceMessage) => {
|
|
21
|
+
switch (message.type) {
|
|
22
|
+
case DOM_MESSAGE_TYPE:
|
|
23
|
+
callback(message.message, remoteObservableDOM);
|
|
24
|
+
break;
|
|
25
|
+
default:
|
|
26
|
+
console.error("Unknown message type", message.type);
|
|
21
27
|
}
|
|
22
28
|
},
|
|
23
29
|
);
|
|
24
30
|
|
|
25
|
-
const remoteObservableDOM:
|
|
26
|
-
|
|
27
|
-
runnerIframe.sendMessageToRunner(
|
|
28
|
-
type: "addConnectedUserId",
|
|
29
|
-
connectionId,
|
|
30
|
-
});
|
|
31
|
+
const remoteObservableDOM: ObservableDOMInterface = observableDOMInterfaceToMessageSender(
|
|
32
|
+
(message: ToObservableDOMInstanceMessage) => {
|
|
33
|
+
runnerIframe.sendMessageToRunner(message);
|
|
31
34
|
},
|
|
32
|
-
|
|
33
|
-
throw new Error("Not implemented");
|
|
34
|
-
},
|
|
35
|
-
dispatchRemoteEventFromConnectionId(connectionId: number, remoteEvent: RemoteEvent): void {
|
|
36
|
-
runnerIframe.sendMessageToRunner({
|
|
37
|
-
type: "dispatchRemoteEventFromConnectionId",
|
|
38
|
-
connectionId,
|
|
39
|
-
event: remoteEvent,
|
|
40
|
-
});
|
|
41
|
-
},
|
|
42
|
-
dispose(): void {
|
|
35
|
+
() => {
|
|
43
36
|
runnerIframe.dispose();
|
|
44
37
|
},
|
|
45
|
-
|
|
46
|
-
runnerIframe.sendMessageToRunner({
|
|
47
|
-
type: "removeConnectedUserId",
|
|
48
|
-
connectionId,
|
|
49
|
-
});
|
|
50
|
-
},
|
|
51
|
-
};
|
|
38
|
+
);
|
|
52
39
|
return remoteObservableDOM;
|
|
53
40
|
};
|
package/src/RunnerIframe.ts
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
FromObservableDOMInstanceMessage,
|
|
3
|
+
ObservableDOMParameters,
|
|
4
|
+
ToObservableDOMInstanceMessage,
|
|
5
|
+
} from "@mml-io/observable-dom-common";
|
|
2
6
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
3
7
|
// @ts-ignore
|
|
4
8
|
// eslint-disable-next-line import/no-unresolved
|
|
5
9
|
import runnerText from "runner-iframe-js-text";
|
|
6
10
|
|
|
7
|
-
import { FromInstanceMessageTypes, ToInstanceMessageTypes } from "./message-types";
|
|
8
|
-
|
|
9
11
|
export class RunnerIframe {
|
|
10
12
|
private iframe: HTMLIFrameElement;
|
|
11
|
-
private onMessageCallback: (
|
|
12
|
-
private postMessageListener: (
|
|
13
|
+
private onMessageCallback: (message: FromObservableDOMInstanceMessage) => void;
|
|
14
|
+
private postMessageListener: (messageEvent: MessageEvent) => void;
|
|
13
15
|
|
|
14
16
|
constructor(
|
|
15
17
|
observableDOMParameters: ObservableDOMParameters,
|
|
16
|
-
onMessageCallback: (
|
|
18
|
+
onMessageCallback: (message: FromObservableDOMInstanceMessage) => void,
|
|
17
19
|
) {
|
|
18
20
|
this.iframe = document.createElement("iframe");
|
|
19
21
|
this.iframe.setAttribute("sandbox", "allow-scripts");
|
|
@@ -62,14 +64,14 @@ export class RunnerIframe {
|
|
|
62
64
|
|
|
63
65
|
this.postMessageListener = (e: MessageEvent) => {
|
|
64
66
|
if (e.source === this.iframe.contentWindow || (isJSDOM && e.source === null)) {
|
|
65
|
-
const parsed = JSON.parse(e.data) as
|
|
67
|
+
const parsed = JSON.parse(e.data) as FromObservableDOMInstanceMessage;
|
|
66
68
|
onMessageCallback(parsed);
|
|
67
69
|
}
|
|
68
70
|
};
|
|
69
71
|
window.addEventListener("message", this.postMessageListener);
|
|
70
72
|
}
|
|
71
73
|
|
|
72
|
-
sendMessageToRunner(message:
|
|
74
|
+
sendMessageToRunner(message: ToObservableDOMInstanceMessage) {
|
|
73
75
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
74
76
|
this.iframe.contentWindow!.postMessage(JSON.stringify(message), "*");
|
|
75
77
|
}
|
package/src/index.ts
CHANGED
package/src/message-types.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { RemoteEvent } from "@mml-io/networked-dom-protocol";
|
|
2
|
-
import { ObservableDomMessage } from "@mml-io/observable-dom-common";
|
|
3
|
-
|
|
4
|
-
export type AddConnectedUserIdMessage = {
|
|
5
|
-
type: "addConnectedUserId";
|
|
6
|
-
connectionId: number;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export type RemoveConnectedUserIdMessage = {
|
|
10
|
-
type: "removeConnectedUserId";
|
|
11
|
-
connectionId: number;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export type DispatchRemoteEventFromConnectionIdMessage = {
|
|
15
|
-
type: "dispatchRemoteEventFromConnectionId";
|
|
16
|
-
connectionId: number;
|
|
17
|
-
event: RemoteEvent;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export type ToInstanceMessageTypes =
|
|
21
|
-
| AddConnectedUserIdMessage
|
|
22
|
-
| RemoveConnectedUserIdMessage
|
|
23
|
-
| DispatchRemoteEventFromConnectionIdMessage;
|
|
24
|
-
|
|
25
|
-
type DOMMessage = {
|
|
26
|
-
type: "dom";
|
|
27
|
-
message: ObservableDomMessage;
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
export type FromInstanceMessageTypes = DOMMessage;
|